@wagmi/connectors 3.1.1-cjs → 4.0.0-alpha.0

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.
Files changed (73) hide show
  1. package/dist/esm/coinbaseWallet.js +141 -0
  2. package/dist/esm/coinbaseWallet.js.map +1 -0
  3. package/dist/esm/index.js +7 -0
  4. package/dist/esm/index.js.map +1 -0
  5. package/dist/esm/index.test-d.js +4 -0
  6. package/dist/esm/index.test-d.js.map +1 -0
  7. package/dist/esm/injected.js +372 -0
  8. package/dist/esm/injected.js.map +1 -0
  9. package/dist/esm/ledger.js +162 -0
  10. package/dist/esm/ledger.js.map +1 -0
  11. package/dist/esm/safe.js +88 -0
  12. package/dist/esm/safe.js.map +1 -0
  13. package/dist/esm/tsconfig.build.tsbuildinfo +1 -0
  14. package/dist/esm/version.js +2 -0
  15. package/dist/esm/version.js.map +1 -0
  16. package/dist/esm/walletConnect.js +280 -0
  17. package/dist/esm/walletConnect.js.map +1 -0
  18. package/dist/types/coinbaseWallet.d.ts +21 -0
  19. package/dist/types/coinbaseWallet.d.ts.map +1 -0
  20. package/dist/types/index.d.ts +7 -0
  21. package/dist/types/index.d.ts.map +1 -0
  22. package/dist/types/index.test-d.d.ts +2 -0
  23. package/dist/types/index.test-d.d.ts.map +1 -0
  24. package/dist/types/injected.d.ts +382 -0
  25. package/dist/types/injected.d.ts.map +1 -0
  26. package/dist/types/ledger.d.ts +18 -0
  27. package/dist/types/ledger.d.ts.map +1 -0
  28. package/dist/types/safe.d.ts +18 -0
  29. package/dist/types/safe.d.ts.map +1 -0
  30. package/dist/types/version.d.ts +2 -0
  31. package/dist/types/version.d.ts.map +1 -0
  32. package/dist/types/walletConnect.d.ts +63 -0
  33. package/dist/types/walletConnect.d.ts.map +1 -0
  34. package/package.json +44 -82
  35. package/src/coinbaseWallet.ts +207 -0
  36. package/src/index.ts +17 -0
  37. package/src/injected.ts +535 -0
  38. package/src/ledger.ts +210 -0
  39. package/src/safe.ts +114 -0
  40. package/src/version.ts +1 -0
  41. package/src/walletConnect.ts +394 -0
  42. package/README.md +0 -46
  43. package/coinbaseWallet/package.json +0 -4
  44. package/dist/base-70e3a8a9.d.ts +0 -142
  45. package/dist/chunk-2UFLHRLT.js +0 -391
  46. package/dist/chunk-OQILYQDO.js +0 -15
  47. package/dist/chunk-UGBGYVBH.js +0 -22
  48. package/dist/chunk-W65LBPLT.js +0 -58
  49. package/dist/coinbaseWallet.d.ts +0 -62
  50. package/dist/coinbaseWallet.js +0 -216
  51. package/dist/index.d.ts +0 -20
  52. package/dist/index.js +0 -16
  53. package/dist/injected.d.ts +0 -64
  54. package/dist/injected.js +0 -9
  55. package/dist/ledger.d.ts +0 -69
  56. package/dist/ledger.js +0 -261
  57. package/dist/metaMask.d.ts +0 -33
  58. package/dist/metaMask.js +0 -144
  59. package/dist/mock/index.d.ts +0 -80
  60. package/dist/mock/index.js +0 -200
  61. package/dist/safe.d.ts +0 -53
  62. package/dist/safe.js +0 -129
  63. package/dist/walletConnect.d.ts +0 -109
  64. package/dist/walletConnect.js +0 -325
  65. package/dist/walletConnectLegacy.d.ts +0 -38
  66. package/dist/walletConnectLegacy.js +0 -179
  67. package/injected/package.json +0 -4
  68. package/ledger/package.json +0 -4
  69. package/metaMask/package.json +0 -4
  70. package/mock/package.json +0 -4
  71. package/safe/package.json +0 -4
  72. package/walletConnect/package.json +0 -4
  73. package/walletConnectLegacy/package.json +0 -4
package/src/ledger.ts ADDED
@@ -0,0 +1,210 @@
1
+ import {
2
+ type EthereumProvider,
3
+ SupportedProviders,
4
+ loadConnectKit,
5
+ } from '@ledgerhq/connect-kit-loader'
6
+ import {
7
+ ChainNotConfiguredError,
8
+ createConnector,
9
+ normalizeChainId,
10
+ } from '@wagmi/core'
11
+ import {
12
+ type ProviderConnectInfo,
13
+ type ProviderRpcError,
14
+ SwitchChainError,
15
+ UserRejectedRequestError,
16
+ getAddress,
17
+ numberToHex,
18
+ } from 'viem'
19
+
20
+ export type LedgerParameters = {
21
+ enableDebugLogs?: boolean | undefined
22
+ optionalEvents?: string[] | undefined
23
+ optionalMethods?: string[] | undefined
24
+ projectId?: string | undefined
25
+ requiredChains?: number[] | undefined
26
+ requiredEvents?: string[] | undefined
27
+ requiredMethods?: string[] | undefined
28
+ }
29
+
30
+ export function ledger(parameters: LedgerParameters = {}) {
31
+ type Provider = EthereumProvider
32
+ type Properties = {
33
+ onConnect(connectInfo: ProviderConnectInfo): void
34
+ onSessionDelete(data: { topic: string }): void
35
+ }
36
+
37
+ let provider_: Provider | undefined
38
+ let providerPromise: Promise<typeof provider_>
39
+
40
+ return createConnector<Provider, Properties>((config) => ({
41
+ id: 'ledger',
42
+ name: 'Ledger',
43
+ async setup() {
44
+ const provider = await this.getProvider()
45
+ if (!provider) return
46
+ provider.on('connect', this.onConnect.bind(this))
47
+ provider.on('session_delete', this.onSessionDelete.bind(this))
48
+ },
49
+ async connect({ chainId } = {}) {
50
+ try {
51
+ const provider = await this.getProvider()
52
+
53
+ // TODO: Update this logic to be more stable (a la WalletConnect connector)
54
+ // Don't request accounts if we have a session, like when reloading with
55
+ // an active WC v2 session
56
+ if (!provider.session)
57
+ await provider.request({ method: 'eth_requestAccounts' })
58
+
59
+ const accounts = await this.getAccounts()
60
+
61
+ provider.removeListener('connect', this.onConnect.bind(this))
62
+ provider.on('accountsChanged', this.onAccountsChanged.bind(this))
63
+ provider.on('chainChanged', this.onChainChanged)
64
+ provider.on('disconnect', this.onDisconnect.bind(this))
65
+ provider.on('session_delete', this.onSessionDelete.bind(this))
66
+
67
+ // Switch to chain if provided
68
+ let currentChainId = await this.getChainId()
69
+ if (chainId && currentChainId !== chainId) {
70
+ const chain = await this.switchChain!({ chainId }).catch(() => ({
71
+ id: currentChainId,
72
+ }))
73
+ currentChainId = chain?.id ?? currentChainId
74
+ }
75
+
76
+ return { accounts, chainId: currentChainId }
77
+ } catch (error) {
78
+ if (/user rejected/i.test((error as ProviderRpcError)?.message))
79
+ throw new UserRejectedRequestError(error as Error)
80
+ throw error
81
+ }
82
+ },
83
+ async disconnect() {
84
+ const provider = await this.getProvider()
85
+ try {
86
+ await provider?.disconnect?.().catch(() => {})
87
+ } catch (error) {
88
+ if (!/No matching key/i.test((error as Error).message)) throw error
89
+ } finally {
90
+ provider.removeListener(
91
+ 'accountsChanged',
92
+ this.onAccountsChanged.bind(this),
93
+ )
94
+ provider.removeListener('chainChanged', this.onChainChanged)
95
+ provider.removeListener('disconnect', this.onDisconnect.bind(this))
96
+ provider.removeListener(
97
+ 'session_delete',
98
+ this.onSessionDelete.bind(this),
99
+ )
100
+ provider.on('connect', this.onConnect.bind(this))
101
+ }
102
+ },
103
+ async getAccounts() {
104
+ const provider = await this.getProvider()
105
+ return (await provider.request<string[]>({ method: 'eth_accounts' })).map(
106
+ getAddress,
107
+ )
108
+ },
109
+ async getProvider({ chainId } = {}) {
110
+ async function initProvider() {
111
+ const connectKit = await loadConnectKit()
112
+ if (parameters.enableDebugLogs) connectKit.enableDebugLogs()
113
+
114
+ const {
115
+ optionalEvents,
116
+ optionalMethods,
117
+ projectId,
118
+ requiredChains,
119
+ requiredEvents,
120
+ requiredMethods,
121
+ } = parameters
122
+ connectKit.checkSupport({
123
+ chains: requiredChains,
124
+ events: requiredEvents,
125
+ methods: requiredMethods,
126
+ optionalChains: config.chains.map(({ id }) => id),
127
+ optionalEvents,
128
+ optionalMethods,
129
+ projectId,
130
+ providerType: SupportedProviders.Ethereum,
131
+ rpcMap: Object.fromEntries(
132
+ config.chains.map((chain) => [
133
+ chain.id,
134
+ chain.rpcUrls.default.http[0]!,
135
+ ]),
136
+ ),
137
+ walletConnectVersion: 2,
138
+ })
139
+
140
+ return (await connectKit.getProvider()) as unknown as EthereumProvider
141
+ }
142
+
143
+ if (!provider_) {
144
+ if (!providerPromise) providerPromise = initProvider()
145
+ provider_ = await providerPromise
146
+ }
147
+ if (chainId) await this.switchChain!({ chainId })
148
+ return provider_!
149
+ },
150
+ async getChainId() {
151
+ const provider = await this.getProvider()
152
+ const chainId = await provider.request({ method: 'eth_chainId' })
153
+ return normalizeChainId(chainId)
154
+ },
155
+ async isAuthorized() {
156
+ try {
157
+ const accounts = await this.getAccounts()
158
+ return !!accounts.length
159
+ } catch {
160
+ return false
161
+ }
162
+ },
163
+ async switchChain({ chainId }) {
164
+ const chain = config.chains.find((chain) => chain.id === chainId)
165
+ if (!chain) throw new SwitchChainError(new ChainNotConfiguredError())
166
+
167
+ try {
168
+ const provider = await this.getProvider()
169
+ await provider.request({
170
+ method: 'wallet_switchEthereumChain',
171
+ params: [{ chainId: numberToHex(chainId) }],
172
+ })
173
+ return chain
174
+ } catch (error) {
175
+ const message =
176
+ typeof error === 'string'
177
+ ? error
178
+ : (error as ProviderRpcError)?.message
179
+ if (/user rejected request/i.test(message))
180
+ throw new UserRejectedRequestError(error as Error)
181
+
182
+ throw new SwitchChainError(error as Error)
183
+ }
184
+ },
185
+ onAccountsChanged(accounts) {
186
+ if (accounts.length === 0) config.emitter.emit('disconnect')
187
+ else config.emitter.emit('change', { accounts: accounts.map(getAddress) })
188
+ },
189
+ onChainChanged(chain) {
190
+ const chainId = normalizeChainId(chain)
191
+ config.emitter.emit('change', { chainId })
192
+ },
193
+ async onConnect(connectInfo) {
194
+ const chainId = normalizeChainId(connectInfo.chainId)
195
+ const accounts = await this.getAccounts()
196
+ config.emitter.emit('connect', { accounts, chainId })
197
+ },
198
+ async onDisconnect(_error) {
199
+ config.emitter.emit('disconnect')
200
+
201
+ const provider = await this.getProvider()
202
+ provider.removeListener('accountsChanged', this.onAccountsChanged)
203
+ provider.removeListener('chainChanged', this.onChainChanged)
204
+ provider.removeListener('disconnect', this.onDisconnect.bind(this))
205
+ },
206
+ onSessionDelete() {
207
+ this.onDisconnect()
208
+ },
209
+ }))
210
+ }
package/src/safe.ts ADDED
@@ -0,0 +1,114 @@
1
+ import { SafeAppProvider } from '@safe-global/safe-apps-provider'
2
+ import { type Opts, default as SafeAppsSDK } from '@safe-global/safe-apps-sdk'
3
+ import { ProviderNotFoundError } from '@wagmi/core'
4
+ import { createConnector, normalizeChainId } from '@wagmi/core'
5
+ import type { Evaluate } from '@wagmi/core/internal'
6
+ import { getAddress } from 'viem'
7
+
8
+ export type SafeParameters = Evaluate<
9
+ Opts & {
10
+ /**
11
+ * Connector automatically connects when used as Safe App.
12
+ *
13
+ * This flag simulates the disconnect behavior by keeping track of connection status in storage
14
+ * and only autoconnecting when previously connected by user action (e.g. explicitly choosing to connect).
15
+ *
16
+ * @default false
17
+ */
18
+ shimDisconnect?: boolean | undefined
19
+ }
20
+ >
21
+
22
+ export function safe(parameters: SafeParameters = {}) {
23
+ type Provider = SafeAppProvider
24
+ type Properties = {}
25
+ type StorageItem = { 'safe.shimDisconnect': true }
26
+
27
+ const shimDisconnectStorageKey = 'safe.shimDisconnect'
28
+
29
+ let provider_: Provider | undefined
30
+ let SDK: typeof SafeAppsSDK.default
31
+ if (
32
+ typeof SafeAppsSDK !== 'function' &&
33
+ typeof SafeAppsSDK.default === 'function'
34
+ )
35
+ SDK = SafeAppsSDK.default
36
+ else SDK = SafeAppsSDK as unknown as typeof SafeAppsSDK.default
37
+ const sdk = new SDK(parameters)
38
+
39
+ return createConnector<Provider, Properties, StorageItem>((config) => ({
40
+ id: 'safe',
41
+ name: 'Safe',
42
+ async connect() {
43
+ // Only allowed in iframe context
44
+ const isIframe =
45
+ typeof window !== 'undefined' && window?.parent !== window
46
+ if (!isIframe) throw new ProviderNotFoundError()
47
+
48
+ const provider = await this.getProvider()
49
+ if (!provider) throw new ProviderNotFoundError()
50
+
51
+ const accounts = await this.getAccounts()
52
+ const chainId = await this.getChainId()
53
+
54
+ provider.on('disconnect', this.onDisconnect.bind(this))
55
+
56
+ // Add shim to storage signalling wallet is connected
57
+ if (parameters.shimDisconnect)
58
+ await config.storage?.setItem(shimDisconnectStorageKey, true)
59
+
60
+ return { accounts, chainId }
61
+ },
62
+ async disconnect() {
63
+ const provider = await this.getProvider()
64
+ provider.removeListener('disconnect', this.onDisconnect.bind(this))
65
+
66
+ // Remove shim signalling wallet is disconnected
67
+ if (parameters.shimDisconnect)
68
+ await config.storage?.removeItem(shimDisconnectStorageKey)
69
+ },
70
+ async getAccounts() {
71
+ const provider = await this.getProvider()
72
+ if (!provider) throw new ProviderNotFoundError()
73
+ return (await provider.request({ method: 'eth_accounts' })).map(
74
+ getAddress,
75
+ )
76
+ },
77
+ async getProvider() {
78
+ if (!provider_) {
79
+ const safe = await sdk.safe.getInfo()
80
+ if (!safe) throw new Error('Could not load Safe information')
81
+ provider_ = new SafeAppProvider(safe, sdk)
82
+ }
83
+ return provider_
84
+ },
85
+ async getChainId() {
86
+ const provider = await this.getProvider()
87
+ if (!provider) throw new ProviderNotFoundError()
88
+ return normalizeChainId(provider.chainId)
89
+ },
90
+ async isAuthorized() {
91
+ try {
92
+ const isDisconnected =
93
+ parameters.shimDisconnect &&
94
+ // If shim does not exist in storage, wallet is disconnected
95
+ !(await config.storage?.getItem(shimDisconnectStorageKey))
96
+ if (isDisconnected) return false
97
+
98
+ const accounts = await this.getAccounts()
99
+ return !!accounts.length
100
+ } catch {
101
+ return false
102
+ }
103
+ },
104
+ onAccountsChanged() {
105
+ // Not relevant for Safe because changing account requires app reload.
106
+ },
107
+ onChainChanged() {
108
+ // Not relevant for Safe because Safe smart contract wallets only exist on single chain.
109
+ },
110
+ onDisconnect() {
111
+ config.emitter.emit('disconnect')
112
+ },
113
+ }))
114
+ }
package/src/version.ts ADDED
@@ -0,0 +1 @@
1
+ export const version = '4.0.0-alpha.0'