@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/metaMask.ts
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
EventType,
|
|
1
|
+
import type {
|
|
3
2
|
MetaMaskSDK,
|
|
4
|
-
|
|
3
|
+
MetaMaskSDKOptions,
|
|
5
4
|
SDKProvider,
|
|
6
5
|
} from '@metamask/sdk'
|
|
6
|
+
import { ChainNotConfiguredError, createConnector } from '@wagmi/core'
|
|
7
|
+
import type { Evaluate, ExactPartial } from '@wagmi/core/internal'
|
|
7
8
|
import {
|
|
8
|
-
|
|
9
|
-
createConnector,
|
|
10
|
-
normalizeChainId,
|
|
11
|
-
} from '@wagmi/core'
|
|
12
|
-
import type { Evaluate, ExactPartial, Omit } from '@wagmi/core/internal'
|
|
13
|
-
import {
|
|
9
|
+
type AddEthereumChainParameter,
|
|
14
10
|
type Address,
|
|
15
11
|
type ProviderConnectInfo,
|
|
16
12
|
type ProviderRpcError,
|
|
@@ -18,31 +14,15 @@ import {
|
|
|
18
14
|
RpcError,
|
|
19
15
|
SwitchChainError,
|
|
20
16
|
UserRejectedRequestError,
|
|
21
|
-
type WalletPermission,
|
|
22
17
|
getAddress,
|
|
23
18
|
numberToHex,
|
|
24
19
|
} from 'viem'
|
|
25
20
|
|
|
26
21
|
export type MetaMaskParameters = Evaluate<
|
|
27
|
-
ExactPartial<
|
|
28
|
-
Omit<
|
|
29
|
-
MetaMaskSDKOptions,
|
|
30
|
-
| 'checkInstallationImmediately'
|
|
31
|
-
| 'checkInstallationOnAllCalls'
|
|
32
|
-
| 'defaultReadOnlyChainId'
|
|
33
|
-
| 'readonlyRPCMap'
|
|
34
|
-
>
|
|
35
|
-
>
|
|
22
|
+
ExactPartial<Omit<MetaMaskSDKOptions, '_source' | 'readonlyRPCMap'>>
|
|
36
23
|
>
|
|
37
24
|
|
|
38
25
|
metaMask.type = 'metaMask' as const
|
|
39
|
-
/**
|
|
40
|
-
* @deprecated
|
|
41
|
-
*
|
|
42
|
-
* __Warning__ This connector has a large file size due to the underlying `@metamask/sdk`. For mobile
|
|
43
|
-
* support, it is recommended to use {@link walletConnect}. For desktop support, you should rely on Multi Injected
|
|
44
|
-
* Provider Discovery (EIP-6963) via the Wagmi {@link Config}.
|
|
45
|
-
*/
|
|
46
26
|
export function metaMask(parameters: MetaMaskParameters = {}) {
|
|
47
27
|
type Provider = SDKProvider
|
|
48
28
|
type Properties = {
|
|
@@ -52,7 +32,8 @@ export function metaMask(parameters: MetaMaskParameters = {}) {
|
|
|
52
32
|
type Listener = Parameters<Provider['on']>[1]
|
|
53
33
|
|
|
54
34
|
let sdk: MetaMaskSDK
|
|
55
|
-
let
|
|
35
|
+
let provider: Provider | undefined
|
|
36
|
+
let providerPromise: Promise<typeof provider>
|
|
56
37
|
|
|
57
38
|
return createConnector<Provider, Properties, StorageItem>((config) => ({
|
|
58
39
|
id: 'metaMaskSDK',
|
|
@@ -66,33 +47,13 @@ export function metaMask(parameters: MetaMaskParameters = {}) {
|
|
|
66
47
|
async connect({ chainId, isReconnecting } = {}) {
|
|
67
48
|
const provider = await this.getProvider()
|
|
68
49
|
|
|
69
|
-
let accounts: readonly Address[]
|
|
70
|
-
if (
|
|
71
|
-
accounts = await this.getAccounts().catch(() => null)
|
|
72
|
-
const isAuthorized = !!accounts?.length
|
|
73
|
-
if (isAuthorized)
|
|
74
|
-
// Attempt to show another prompt for selecting account if already connected
|
|
75
|
-
try {
|
|
76
|
-
const permissions = (await provider.request({
|
|
77
|
-
method: 'wallet_requestPermissions',
|
|
78
|
-
params: [{ eth_accounts: {} }],
|
|
79
|
-
})) as WalletPermission[]
|
|
80
|
-
accounts = permissions[0]?.caveats?.[0]?.value?.map(getAddress)
|
|
81
|
-
} catch (err) {
|
|
82
|
-
const error = err as RpcError
|
|
83
|
-
// Not all injected providers support `wallet_requestPermissions` (e.g. MetaMask iOS).
|
|
84
|
-
// Only bubble up error if user rejects request
|
|
85
|
-
if (error.code === UserRejectedRequestError.code)
|
|
86
|
-
throw new UserRejectedRequestError(error)
|
|
87
|
-
// Or prompt is already open
|
|
88
|
-
if (error.code === ResourceUnavailableRpcError.code) throw error
|
|
89
|
-
}
|
|
90
|
-
}
|
|
50
|
+
let accounts: readonly Address[] = []
|
|
51
|
+
if (isReconnecting) accounts = await this.getAccounts().catch(() => [])
|
|
91
52
|
|
|
92
53
|
try {
|
|
93
54
|
if (!accounts?.length) {
|
|
94
55
|
const requestedAccounts = (await sdk.connect()) as string[]
|
|
95
|
-
accounts = requestedAccounts.map(getAddress)
|
|
56
|
+
accounts = requestedAccounts.map((x) => getAddress(x))
|
|
96
57
|
}
|
|
97
58
|
|
|
98
59
|
provider.removeListener(
|
|
@@ -106,20 +67,8 @@ export function metaMask(parameters: MetaMaskParameters = {}) {
|
|
|
106
67
|
provider.on('chainChanged', this.onChainChanged as Listener)
|
|
107
68
|
provider.on('disconnect', this.onDisconnect.bind(this) as Listener)
|
|
108
69
|
|
|
109
|
-
// Backward compatibility with older wallet (<7.3) version that return accounts before authorization
|
|
110
|
-
if (!sdk.isExtensionActive() && !sdk._getConnection()?.isAuthorized()) {
|
|
111
|
-
function waitForAuthorized() {
|
|
112
|
-
return new Promise((resolve) => {
|
|
113
|
-
const connection = sdk._getConnection()
|
|
114
|
-
const connector = connection?.getConnector()
|
|
115
|
-
connector?.once(EventType.AUTHORIZED, () => resolve(true))
|
|
116
|
-
})
|
|
117
|
-
}
|
|
118
|
-
await waitForAuthorized()
|
|
119
|
-
}
|
|
120
|
-
|
|
121
70
|
// Switch to chain if provided
|
|
122
|
-
let currentChainId = await this.getChainId()
|
|
71
|
+
let currentChainId = (await this.getChainId()) as number
|
|
123
72
|
if (chainId && currentChainId !== chainId) {
|
|
124
73
|
const chain = await this.switchChain!({ chainId }).catch((error) => {
|
|
125
74
|
if (error.code === UserRejectedRequestError.code) throw error
|
|
@@ -161,48 +110,62 @@ export function metaMask(parameters: MetaMaskParameters = {}) {
|
|
|
161
110
|
const accounts = (await provider.request({
|
|
162
111
|
method: 'eth_accounts',
|
|
163
112
|
})) as string[]
|
|
164
|
-
return accounts.map(getAddress)
|
|
113
|
+
return accounts.map((x) => getAddress(x))
|
|
165
114
|
},
|
|
166
115
|
async getChainId() {
|
|
167
116
|
const provider = await this.getProvider()
|
|
168
117
|
const chainId =
|
|
169
|
-
provider.
|
|
170
|
-
|
|
118
|
+
provider.getChainId() ||
|
|
119
|
+
(await provider?.request({ method: 'eth_chainId' }))
|
|
120
|
+
return Number(chainId)
|
|
171
121
|
},
|
|
172
122
|
async getProvider() {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
123
|
+
async function initProvider() {
|
|
124
|
+
// Unwrapping import for Vite compatibility.
|
|
125
|
+
// See: https://github.com/vitejs/vite/issues/9703
|
|
126
|
+
const { default: MetaMaskSDK_ } = await import('@metamask/sdk')
|
|
127
|
+
const MetaMaskSDK = (() => {
|
|
128
|
+
if (
|
|
129
|
+
typeof MetaMaskSDK_ !== 'function' &&
|
|
130
|
+
typeof MetaMaskSDK_.default === 'function'
|
|
131
|
+
)
|
|
132
|
+
return MetaMaskSDK_.default
|
|
133
|
+
return MetaMaskSDK_ as unknown as typeof MetaMaskSDK_.default
|
|
134
|
+
})()
|
|
135
|
+
|
|
136
|
+
sdk = new MetaMaskSDK({
|
|
137
|
+
dappMetadata: {},
|
|
138
|
+
...parameters,
|
|
139
|
+
_source: 'wagmi',
|
|
140
|
+
readonlyRPCMap: Object.fromEntries(
|
|
141
|
+
config.chains.map((chain) => [
|
|
142
|
+
chain.id,
|
|
143
|
+
chain.rpcUrls.default.http[0]!,
|
|
144
|
+
]),
|
|
145
|
+
),
|
|
146
|
+
})
|
|
147
|
+
await sdk.init()
|
|
148
|
+
return sdk.getProvider()!
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (!provider) {
|
|
152
|
+
if (!providerPromise) providerPromise = initProvider()
|
|
153
|
+
provider = await providerPromise
|
|
201
154
|
}
|
|
202
|
-
return
|
|
155
|
+
return provider!
|
|
203
156
|
},
|
|
204
157
|
async isAuthorized() {
|
|
205
158
|
try {
|
|
159
|
+
const isMobileBrowser =
|
|
160
|
+
typeof navigator !== 'undefined'
|
|
161
|
+
? /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
|
|
162
|
+
navigator.userAgent,
|
|
163
|
+
)
|
|
164
|
+
: false
|
|
165
|
+
|
|
166
|
+
// MetaMask Mobile doesn't support persisted sessions.
|
|
167
|
+
if (isMobileBrowser) return false
|
|
168
|
+
|
|
206
169
|
const isDisconnected =
|
|
207
170
|
// If shim exists in storage, connector is disconnected
|
|
208
171
|
await config.storage?.getItem('metaMaskSDK.disconnected')
|
|
@@ -214,7 +177,7 @@ export function metaMask(parameters: MetaMaskParameters = {}) {
|
|
|
214
177
|
return false
|
|
215
178
|
}
|
|
216
179
|
},
|
|
217
|
-
async switchChain({ chainId }) {
|
|
180
|
+
async switchChain({ addEthereumChainParameter, chainId }) {
|
|
218
181
|
const provider = await this.getProvider()
|
|
219
182
|
|
|
220
183
|
const chain = config.chains.find((x) => x.id === chainId)
|
|
@@ -247,24 +210,34 @@ export function metaMask(parameters: MetaMaskParameters = {}) {
|
|
|
247
210
|
try {
|
|
248
211
|
const { default: blockExplorer, ...blockExplorers } =
|
|
249
212
|
chain.blockExplorers ?? {}
|
|
250
|
-
let blockExplorerUrls
|
|
251
|
-
if (
|
|
213
|
+
let blockExplorerUrls
|
|
214
|
+
if (addEthereumChainParameter?.blockExplorerUrls)
|
|
215
|
+
blockExplorerUrls = addEthereumChainParameter.blockExplorerUrls
|
|
216
|
+
else if (blockExplorer)
|
|
252
217
|
blockExplorerUrls = [
|
|
253
218
|
blockExplorer.url,
|
|
254
219
|
...Object.values(blockExplorers).map((x) => x.url),
|
|
255
220
|
]
|
|
256
221
|
|
|
222
|
+
let rpcUrls
|
|
223
|
+
if (addEthereumChainParameter?.rpcUrls?.length)
|
|
224
|
+
rpcUrls = addEthereumChainParameter.rpcUrls
|
|
225
|
+
else rpcUrls = [chain.rpcUrls.default?.http[0] ?? '']
|
|
226
|
+
|
|
227
|
+
const addEthereumChain = {
|
|
228
|
+
blockExplorerUrls,
|
|
229
|
+
chainId: numberToHex(chainId),
|
|
230
|
+
chainName: addEthereumChainParameter?.chainName ?? chain.name,
|
|
231
|
+
iconUrls: addEthereumChainParameter?.iconUrls,
|
|
232
|
+
nativeCurrency:
|
|
233
|
+
addEthereumChainParameter?.nativeCurrency ??
|
|
234
|
+
chain.nativeCurrency,
|
|
235
|
+
rpcUrls,
|
|
236
|
+
} satisfies AddEthereumChainParameter
|
|
237
|
+
|
|
257
238
|
await provider.request({
|
|
258
239
|
method: 'wallet_addEthereumChain',
|
|
259
|
-
params: [
|
|
260
|
-
{
|
|
261
|
-
chainId: numberToHex(chainId),
|
|
262
|
-
chainName: chain.name,
|
|
263
|
-
nativeCurrency: chain.nativeCurrency,
|
|
264
|
-
rpcUrls: [chain.rpcUrls.default?.http[0] ?? ''],
|
|
265
|
-
blockExplorerUrls,
|
|
266
|
-
},
|
|
267
|
-
],
|
|
240
|
+
params: [addEthereumChain],
|
|
268
241
|
})
|
|
269
242
|
|
|
270
243
|
const currentChainId = await this.getChainId()
|
|
@@ -294,17 +267,20 @@ export function metaMask(parameters: MetaMaskParameters = {}) {
|
|
|
294
267
|
await config.storage?.removeItem('metaMaskSDK.disconnected')
|
|
295
268
|
}
|
|
296
269
|
// Regular change event
|
|
297
|
-
else
|
|
270
|
+
else
|
|
271
|
+
config.emitter.emit('change', {
|
|
272
|
+
accounts: accounts.map((x) => getAddress(x)),
|
|
273
|
+
})
|
|
298
274
|
},
|
|
299
275
|
onChainChanged(chain) {
|
|
300
|
-
const chainId =
|
|
276
|
+
const chainId = Number(chain)
|
|
301
277
|
config.emitter.emit('change', { chainId })
|
|
302
278
|
},
|
|
303
279
|
async onConnect(connectInfo) {
|
|
304
280
|
const accounts = await this.getAccounts()
|
|
305
281
|
if (accounts.length === 0) return
|
|
306
282
|
|
|
307
|
-
const chainId =
|
|
283
|
+
const chainId = Number(connectInfo.chainId)
|
|
308
284
|
config.emitter.emit('connect', { accounts, chainId })
|
|
309
285
|
|
|
310
286
|
const provider = await this.getProvider()
|
|
@@ -324,6 +300,12 @@ export function metaMask(parameters: MetaMaskParameters = {}) {
|
|
|
324
300
|
if (provider && !!(await this.getAccounts()).length) return
|
|
325
301
|
}
|
|
326
302
|
|
|
303
|
+
// Remove cached SDK properties.
|
|
304
|
+
if (typeof localStorage !== 'undefined') {
|
|
305
|
+
localStorage.removeItem('MMSDK_cached_address')
|
|
306
|
+
localStorage.removeItem('MMSDK_cached_chainId')
|
|
307
|
+
}
|
|
308
|
+
|
|
327
309
|
// No need to remove 'metaMaskSDK.disconnected' from storage because `onDisconnect` is typically
|
|
328
310
|
// only called when the wallet is disconnected through the wallet's interface, meaning the wallet
|
|
329
311
|
// actually disconnected and we don't need to simulate it.
|
package/src/safe.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { SafeAppProvider } from '@safe-global/safe-apps-provider'
|
|
2
|
-
import {
|
|
1
|
+
import type { SafeAppProvider } from '@safe-global/safe-apps-provider'
|
|
2
|
+
import type { Opts } from '@safe-global/safe-apps-sdk'
|
|
3
3
|
import {
|
|
4
|
+
type Connector,
|
|
4
5
|
ProviderNotFoundError,
|
|
5
6
|
createConnector,
|
|
6
|
-
normalizeChainId,
|
|
7
7
|
} from '@wagmi/core'
|
|
8
8
|
import type { Evaluate } from '@wagmi/core/internal'
|
|
9
9
|
import { getAddress } from 'viem'
|
|
@@ -31,14 +31,8 @@ export function safe(parameters: SafeParameters = {}) {
|
|
|
31
31
|
type StorageItem = { 'safe.disconnected': true }
|
|
32
32
|
|
|
33
33
|
let provider_: Provider | undefined
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
typeof SafeAppsSDK !== 'function' &&
|
|
37
|
-
typeof SafeAppsSDK.default === 'function'
|
|
38
|
-
)
|
|
39
|
-
SDK = SafeAppsSDK.default
|
|
40
|
-
else SDK = SafeAppsSDK as unknown as typeof SafeAppsSDK.default
|
|
41
|
-
const sdk = new SDK(parameters)
|
|
34
|
+
|
|
35
|
+
let disconnect: Connector['onDisconnect'] | undefined
|
|
42
36
|
|
|
43
37
|
return createConnector<Provider, Properties, StorageItem>((config) => ({
|
|
44
38
|
id: 'safe',
|
|
@@ -51,7 +45,10 @@ export function safe(parameters: SafeParameters = {}) {
|
|
|
51
45
|
const accounts = await this.getAccounts()
|
|
52
46
|
const chainId = await this.getChainId()
|
|
53
47
|
|
|
54
|
-
|
|
48
|
+
if (!disconnect) {
|
|
49
|
+
disconnect = this.onDisconnect.bind(this)
|
|
50
|
+
provider.on('disconnect', disconnect)
|
|
51
|
+
}
|
|
55
52
|
|
|
56
53
|
// Remove disconnected shim if it exists
|
|
57
54
|
if (shimDisconnect) await config.storage?.removeItem('safe.disconnected')
|
|
@@ -62,7 +59,10 @@ export function safe(parameters: SafeParameters = {}) {
|
|
|
62
59
|
const provider = await this.getProvider()
|
|
63
60
|
if (!provider) throw new ProviderNotFoundError()
|
|
64
61
|
|
|
65
|
-
|
|
62
|
+
if (disconnect) {
|
|
63
|
+
provider.removeListener('disconnect', disconnect)
|
|
64
|
+
disconnect = undefined
|
|
65
|
+
}
|
|
66
66
|
|
|
67
67
|
// Add shim signalling connector is disconnected
|
|
68
68
|
if (shimDisconnect)
|
|
@@ -82,8 +82,23 @@ export function safe(parameters: SafeParameters = {}) {
|
|
|
82
82
|
if (!isIframe) return
|
|
83
83
|
|
|
84
84
|
if (!provider_) {
|
|
85
|
+
const { default: SafeAppsSDK } = await import(
|
|
86
|
+
'@safe-global/safe-apps-sdk'
|
|
87
|
+
)
|
|
88
|
+
let SDK: typeof SafeAppsSDK.default
|
|
89
|
+
if (
|
|
90
|
+
typeof SafeAppsSDK !== 'function' &&
|
|
91
|
+
typeof SafeAppsSDK.default === 'function'
|
|
92
|
+
)
|
|
93
|
+
SDK = SafeAppsSDK.default
|
|
94
|
+
else SDK = SafeAppsSDK as unknown as typeof SafeAppsSDK.default
|
|
95
|
+
const sdk = new SDK(parameters)
|
|
96
|
+
|
|
85
97
|
const safe = await sdk.safe.getInfo()
|
|
86
98
|
if (!safe) throw new Error('Could not load Safe information')
|
|
99
|
+
const { SafeAppProvider } = await import(
|
|
100
|
+
'@safe-global/safe-apps-provider'
|
|
101
|
+
)
|
|
87
102
|
provider_ = new SafeAppProvider(safe, sdk)
|
|
88
103
|
}
|
|
89
104
|
return provider_
|
|
@@ -91,7 +106,7 @@ export function safe(parameters: SafeParameters = {}) {
|
|
|
91
106
|
async getChainId() {
|
|
92
107
|
const provider = await this.getProvider()
|
|
93
108
|
if (!provider) throw new ProviderNotFoundError()
|
|
94
|
-
return
|
|
109
|
+
return Number(provider.chainId)
|
|
95
110
|
},
|
|
96
111
|
async isAuthorized() {
|
|
97
112
|
try {
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '5.0.
|
|
1
|
+
export const version = '5.0.2'
|