@wagmi/connectors 0.2.7 → 0.3.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.
@@ -1,27 +1,69 @@
1
- import * as _walletconnect_universal_provider from '@walletconnect/universal-provider';
2
- import { UniversalProvider as UniversalProvider$1, UniversalProviderOpts } from '@walletconnect/universal-provider';
3
1
  import { Chain } from '@wagmi/core';
4
2
  import WalletConnectProvider from '@walletconnect/ethereum-provider';
3
+ import { EthereumProviderOptions } from '@walletconnect/ethereum-provider/dist/types/EthereumProvider';
5
4
  import { providers } from 'ethers';
6
5
  import { C as Connector } from './base-84a689bb.js';
7
6
  import '@wagmi/core/chains';
8
7
  import 'eventemitter3';
9
8
 
10
- type UniversalProvider = InstanceType<typeof UniversalProvider$1>;
11
9
  type WalletConnectOptions = {
12
- /** When `true`, uses default WalletConnect QR Code modal */
13
- qrcode?: boolean;
14
- } & (({
15
- version?: '1';
16
- } & ConstructorParameters<typeof WalletConnectProvider>[0]) | ({
17
10
  /**
18
- * Project ID associated with [WalletConnect account](https://cloud.walletconnect.com)
11
+ * WalletConnect Cloud Project ID.
12
+ * @link https://cloud.walletconnect.com/sign-in.
19
13
  */
20
- projectId: NonNullable<UniversalProviderOpts['projectId']>;
21
- version: '2';
22
- } & Omit<UniversalProviderOpts, 'projectId'>));
14
+ projectId: EthereumProviderOptions['projectId'];
15
+ /**
16
+ * If a new chain is added to a previously existing configured connector `chains`, this flag
17
+ * will determine if that chain should be considered as stale. A stale chain is a chain that
18
+ * WalletConnect has yet to establish a relationship with (ie. the user has not approved or
19
+ * rejected the chain).
20
+ * Defaults to `true`.
21
+ *
22
+ * Preface: Whereas WalletConnect v1 supported dynamic chain switching, WalletConnect v2 requires
23
+ * the user to pre-approve a set of chains up-front. This comes with consequent UX nuances (see below) when
24
+ * a user tries to switch to a chain that they have not approved.
25
+ *
26
+ * This flag mainly affects the behavior when a wallet does not support dynamic chain authorization
27
+ * with WalletConnect v2.
28
+ *
29
+ * If `true` (default), the new chain will be treated as a stale chain. If the user
30
+ * has yet to establish a relationship (approved/rejected) with this chain in their WalletConnect
31
+ * session, the connector will disconnect upon the dapp auto-connecting, and the user will have to
32
+ * reconnect to the dapp (revalidate the chain) in order to approve the newly added chain.
33
+ * This is the default behavior to avoid an unexpected error upon switching chains which may
34
+ * be a confusing user experience (ie. the user will not know they have to reconnect
35
+ * unless the dapp handles these types of errors).
36
+ *
37
+ * If `false`, the new chain will be treated as a validated chain. This means that if the user
38
+ * has yet to establish a relationship with the chain in their WalletConnect session, wagmi will successfully
39
+ * auto-connect the user. This comes with the trade-off that the connector will throw an error
40
+ * when attempting to switch to the unapproved chain. This may be useful in cases where a dapp constantly
41
+ * modifies their configured chains, and they do not want to disconnect the user upon
42
+ * auto-connecting. If the user decides to switch to the unapproved chain, it is important that the
43
+ * dapp handles this error and prompts the user to reconnect to the dapp in order to approve
44
+ * the newly added chain.
45
+ *
46
+ */
47
+ isNewChainsStale?: boolean;
48
+ /**
49
+ * Metadata for your app.
50
+ * @link https://docs.walletconnect.com/2.0/javascript/providers/ethereum#initialization
51
+ */
52
+ metadata?: EthereumProviderOptions['metadata'];
53
+ /**
54
+ * Whether or not to show the QR code modal.
55
+ * @link https://docs.walletconnect.com/2.0/javascript/providers/ethereum#initialization
56
+ */
57
+ showQrModal?: EthereumProviderOptions['showQrModal'];
58
+ };
23
59
  type WalletConnectSigner = providers.JsonRpcSigner;
24
- declare class WalletConnectConnector extends Connector<WalletConnectProvider | UniversalProvider, WalletConnectOptions, WalletConnectSigner> {
60
+ type ConnectConfig = {
61
+ /** Target chain to connect to. */
62
+ chainId?: number;
63
+ /** If provided, will attempt to connect to an existing pairing. */
64
+ pairingTopic?: string;
65
+ };
66
+ declare class WalletConnectConnector extends Connector<WalletConnectProvider, WalletConnectOptions, WalletConnectSigner> {
25
67
  #private;
26
68
  readonly id = "walletConnect";
27
69
  readonly name = "WalletConnect";
@@ -30,12 +72,7 @@ declare class WalletConnectConnector extends Connector<WalletConnectProvider | U
30
72
  chains?: Chain[];
31
73
  options: WalletConnectOptions;
32
74
  });
33
- get isQrCode(): boolean;
34
- get namespacedChains(): string[];
35
- get version(): "1" | "2" | undefined;
36
- connect({ chainId }?: {
37
- chainId?: number;
38
- }): Promise<{
75
+ connect({ chainId, pairingTopic }?: ConnectConfig): Promise<{
39
76
  account: `0x${string}`;
40
77
  chain: {
41
78
  id: number;
@@ -46,18 +83,19 @@ declare class WalletConnectConnector extends Connector<WalletConnectProvider | U
46
83
  disconnect(): Promise<void>;
47
84
  getAccount(): Promise<`0x${string}`>;
48
85
  getChainId(): Promise<number>;
49
- getProvider({ chainId, create, }?: {
86
+ getProvider({ chainId }?: {
50
87
  chainId?: number;
51
- create?: boolean;
52
- }): Promise<_walletconnect_universal_provider.default | WalletConnectProvider>;
88
+ }): Promise<WalletConnectProvider>;
53
89
  getSigner({ chainId }?: {
54
90
  chainId?: number;
55
91
  }): Promise<providers.JsonRpcSigner>;
56
92
  isAuthorized(): Promise<boolean>;
93
+ switchChain(chainId: number): Promise<Chain>;
57
94
  protected onAccountsChanged: (accounts: string[]) => void;
58
95
  protected onChainChanged: (chainId: number | string) => void;
59
96
  protected onDisconnect: () => void;
60
97
  protected onDisplayUri: (uri: string) => void;
98
+ protected onConnect: () => void;
61
99
  }
62
100
 
63
101
  export { WalletConnectConnector };
@@ -11,42 +11,34 @@ import {
11
11
  import {
12
12
  SwitchChainError,
13
13
  UserRejectedRequestError,
14
- getClient,
15
- normalizeChainId
14
+ getClient
16
15
  } from "@wagmi/core";
17
16
  import { providers } from "ethers";
18
17
  import { getAddress, hexValue } from "ethers/lib/utils.js";
19
- var defaultV2Config = {
20
- namespace: "eip155",
21
- methods: [
22
- "eth_sendTransaction",
23
- "eth_sendRawTransaction",
24
- "eth_sign",
25
- "eth_signTransaction",
26
- "eth_signTypedData",
27
- "eth_signTypedData_v3",
28
- "eth_signTypedData_v4",
29
- "personal_sign",
30
- "wallet_switchEthereumChain",
31
- "wallet_addEthereumChain"
32
- ],
33
- events: ["accountsChanged", "chainChanged"]
34
- };
35
- var _provider, _initUniversalProviderPromise, _web3Modal, _createWeb3Modal, createWeb3Modal_fn, _initUniversalProvider, initUniversalProvider_fn, _createUniversalProvider, createUniversalProvider_fn, _isChainsAuthorized, isChainsAuthorized_fn, _switchChain, switchChain_fn;
18
+ var NAMESPACE = "eip155";
19
+ var REQUESTED_CHAINS_KEY = "wagmi.requestedChains";
20
+ var ADD_ETH_CHAIN_METHOD = "wallet_addEthereumChain";
21
+ var _provider, _initProviderPromise, _createProvider, createProvider_fn, _initProvider, initProvider_fn, _isChainsStale, isChainsStale_fn, _setupListeners, setupListeners_fn, _removeListeners, removeListeners_fn, _setRequestedChainsIds, setRequestedChainsIds_fn, _getRequestedChainsIds, getRequestedChainsIds_fn, _getNamespaceChainsIds, getNamespaceChainsIds_fn, _getNamespaceMethods, getNamespaceMethods_fn;
36
22
  var WalletConnectConnector = class extends Connector {
37
23
  constructor(config) {
38
- super(config);
39
- __privateAdd(this, _createWeb3Modal);
40
- __privateAdd(this, _initUniversalProvider);
41
- __privateAdd(this, _createUniversalProvider);
42
- __privateAdd(this, _isChainsAuthorized);
43
- __privateAdd(this, _switchChain);
24
+ super({
25
+ ...config,
26
+ options: { isNewChainsStale: true, ...config.options }
27
+ });
28
+ __privateAdd(this, _createProvider);
29
+ __privateAdd(this, _initProvider);
30
+ __privateAdd(this, _isChainsStale);
31
+ __privateAdd(this, _setupListeners);
32
+ __privateAdd(this, _removeListeners);
33
+ __privateAdd(this, _setRequestedChainsIds);
34
+ __privateAdd(this, _getRequestedChainsIds);
35
+ __privateAdd(this, _getNamespaceChainsIds);
36
+ __privateAdd(this, _getNamespaceMethods);
44
37
  __publicField(this, "id", "walletConnect");
45
38
  __publicField(this, "name", "WalletConnect");
46
39
  __publicField(this, "ready", true);
47
40
  __privateAdd(this, _provider, void 0);
48
- __privateAdd(this, _initUniversalProviderPromise, void 0);
49
- __privateAdd(this, _web3Modal, void 0);
41
+ __privateAdd(this, _initProviderPromise, void 0);
50
42
  __publicField(this, "onAccountsChanged", (accounts) => {
51
43
  if (accounts.length === 0)
52
44
  this.emit("disconnect");
@@ -54,127 +46,60 @@ var WalletConnectConnector = class extends Connector {
54
46
  this.emit("change", { account: getAddress(accounts[0]) });
55
47
  });
56
48
  __publicField(this, "onChainChanged", (chainId) => {
57
- const id = normalizeChainId(chainId);
49
+ const id = Number(chainId);
58
50
  const unsupported = this.isChainUnsupported(id);
59
51
  this.emit("change", { chain: { id, unsupported } });
60
52
  });
61
53
  __publicField(this, "onDisconnect", () => {
54
+ __privateMethod(this, _setRequestedChainsIds, setRequestedChainsIds_fn).call(this, []);
62
55
  this.emit("disconnect");
63
56
  });
64
57
  __publicField(this, "onDisplayUri", (uri) => {
65
58
  this.emit("message", { type: "display_uri", data: uri });
66
59
  });
67
- if (this.version === "2") {
68
- __privateMethod(this, _createUniversalProvider, createUniversalProvider_fn).call(this);
69
- if (this.isQrCode)
70
- __privateMethod(this, _createWeb3Modal, createWeb3Modal_fn).call(this);
71
- }
72
- }
73
- get isQrCode() {
74
- return this.options.qrcode !== false;
75
- }
76
- get namespacedChains() {
77
- return this.chains.map(
78
- (chain) => `${defaultV2Config.namespace}:${chain.id}`
79
- );
80
- }
81
- get version() {
82
- if ("version" in this.options)
83
- return this.options.version;
84
- return "1";
60
+ __publicField(this, "onConnect", () => {
61
+ this.emit("connect", { provider: __privateGet(this, _provider) });
62
+ });
63
+ __privateMethod(this, _createProvider, createProvider_fn).call(this);
85
64
  }
86
- async connect({ chainId } = {}) {
87
- const isV1 = this.version === "1";
88
- const isV2 = this.version === "2";
65
+ async connect({ chainId, pairingTopic } = {}) {
89
66
  try {
90
67
  let targetChainId = chainId;
91
68
  if (!targetChainId) {
92
69
  const lastUsedChainId = getClient().lastUsedChainId;
93
70
  if (lastUsedChainId && !this.isChainUnsupported(lastUsedChainId))
94
71
  targetChainId = lastUsedChainId;
72
+ else
73
+ targetChainId = this.chains[0]?.id;
95
74
  }
96
- const provider = await this.getProvider({
97
- chainId: targetChainId,
98
- create: isV1
99
- });
100
- provider.on("accountsChanged", this.onAccountsChanged);
101
- provider.on("chainChanged", this.onChainChanged);
102
- provider.on("disconnect", this.onDisconnect);
103
- if (isV2) {
104
- provider.on("session_delete", this.onDisconnect);
105
- provider.on("display_uri", this.onDisplayUri);
106
- const isChainsAuthorized = await __privateMethod(this, _isChainsAuthorized, isChainsAuthorized_fn).call(this);
107
- if (provider.session && !isChainsAuthorized)
108
- await provider.disconnect();
109
- if (!provider.session || provider.session && !isChainsAuthorized) {
110
- await Promise.race([
111
- provider.connect({
112
- namespaces: {
113
- [defaultV2Config.namespace]: {
114
- methods: defaultV2Config.methods,
115
- events: defaultV2Config.events,
116
- chains: this.namespacedChains,
117
- rpcMap: this.chains.reduce(
118
- (rpc, chain) => ({
119
- ...rpc,
120
- [chain.id]: chain.rpcUrls.default.http[0]
121
- }),
122
- {}
123
- )
124
- }
125
- }
126
- }),
127
- ...this.isQrCode ? [
128
- new Promise(
129
- (_resolve, reject) => provider.on("display_uri", async (uri) => {
130
- await __privateGet(this, _web3Modal)?.openModal({ uri });
131
- __privateGet(this, _web3Modal)?.subscribeModal(({ open }) => {
132
- if (!open)
133
- reject(new Error("user rejected"));
134
- });
135
- })
136
- )
137
- ] : []
138
- ]);
139
- if (this.isQrCode)
140
- __privateGet(this, _web3Modal)?.closeModal();
141
- }
75
+ if (!targetChainId)
76
+ throw new Error("No chains found on connector.");
77
+ const provider = await this.getProvider();
78
+ __privateMethod(this, _setupListeners, setupListeners_fn).call(this);
79
+ const isChainsStale = __privateMethod(this, _isChainsStale, isChainsStale_fn).call(this);
80
+ if (provider.session && isChainsStale)
81
+ await provider.disconnect();
82
+ if (!provider.session || isChainsStale) {
83
+ const optionalChains = this.chains.filter((chain) => chain.id !== targetChainId).map((optionalChain) => optionalChain.id);
84
+ this.emit("message", { type: "connecting" });
85
+ await provider.connect({
86
+ pairingTopic,
87
+ chains: [targetChainId],
88
+ optionalChains
89
+ });
90
+ __privateMethod(this, _setRequestedChainsIds, setRequestedChainsIds_fn).call(this, this.chains.map(({ id: id2 }) => id2));
142
91
  }
143
- setTimeout(() => this.emit("message", { type: "connecting" }), 0);
144
- const accounts = await Promise.race([
145
- provider.enable(),
146
- ...isV1 && this.isQrCode ? [
147
- new Promise(
148
- (_res, reject) => provider.connector.on(
149
- "disconnect",
150
- () => reject(new Error("user rejected"))
151
- )
152
- )
153
- ] : []
154
- ]);
92
+ const accounts = await provider.enable();
155
93
  const account = getAddress(accounts[0]);
156
94
  const id = await this.getChainId();
157
95
  const unsupported = this.isChainUnsupported(id);
158
- if (isV1) {
159
- const walletName = provider.connector?.peerMeta?.name ?? "";
160
- const switchChainAllowedRegex = /(imtoken|metamask|omni|rainbow|trust wallet)/i;
161
- if (switchChainAllowedRegex.test(walletName))
162
- this.switchChain = __privateMethod(this, _switchChain, switchChain_fn);
163
- } else
164
- this.switchChain = __privateMethod(this, _switchChain, switchChain_fn);
165
96
  return {
166
97
  account,
167
98
  chain: { id, unsupported },
168
- provider: new providers.Web3Provider(
169
- provider
170
- )
99
+ provider: new providers.Web3Provider(provider)
171
100
  };
172
101
  } catch (error) {
173
- if (isV2 && this.isQrCode)
174
- __privateGet(this, _web3Modal)?.closeModal();
175
- if (/user closed modal|user rejected/i.test(
176
- error?.message
177
- )) {
102
+ if (/user rejected/i.test(error?.message)) {
178
103
  throw new UserRejectedRequestError(error);
179
104
  }
180
105
  throw error;
@@ -187,62 +112,24 @@ var WalletConnectConnector = class extends Connector {
187
112
  } catch (error) {
188
113
  if (!/No matching key/i.test(error.message))
189
114
  throw error;
190
- }
191
- provider.removeListener("accountsChanged", this.onAccountsChanged);
192
- provider.removeListener("chainChanged", this.onChainChanged);
193
- provider.removeListener("disconnect", this.onDisconnect);
194
- if (this.version === "1" && typeof localStorage !== "undefined")
195
- localStorage.removeItem("walletconnect");
196
- else {
197
- provider.removeListener("session_delete", this.onDisconnect);
198
- provider.removeListener("display_uri", this.onDisplayUri);
115
+ } finally {
116
+ __privateMethod(this, _removeListeners, removeListeners_fn).call(this);
117
+ __privateMethod(this, _setRequestedChainsIds, setRequestedChainsIds_fn).call(this, []);
199
118
  }
200
119
  }
201
120
  async getAccount() {
202
- const provider = await this.getProvider();
203
- let accounts;
204
- if (this.version === "1")
205
- accounts = provider.accounts;
206
- else
207
- accounts = await provider.request({
208
- method: "eth_accounts"
209
- });
121
+ const { accounts } = await this.getProvider();
210
122
  return getAddress(accounts[0]);
211
123
  }
212
124
  async getChainId() {
213
- const provider = await this.getProvider();
214
- if (this.version === "1")
215
- return normalizeChainId(provider.chainId);
216
- return getClient().data?.chain?.id ?? normalizeChainId(await provider.request({ method: "eth_chainId" }));
125
+ const { chainId } = await this.getProvider();
126
+ return chainId;
217
127
  }
218
- async getProvider({
219
- chainId,
220
- create
221
- } = {}) {
222
- if (this.options.version === "2") {
223
- if (!__privateGet(this, _provider))
224
- await __privateMethod(this, _createUniversalProvider, createUniversalProvider_fn).call(this);
225
- if (chainId)
226
- __privateGet(this, _provider).setDefaultChain(
227
- `${defaultV2Config.namespace}:${chainId}`
228
- );
229
- return __privateGet(this, _provider);
230
- } else if (!__privateGet(this, _provider) || chainId || create) {
231
- const rpc = !this.options?.infuraId ? this.chains.reduce(
232
- (rpc2, chain) => ({
233
- ...rpc2,
234
- [chain.id]: chain.rpcUrls.default.http[0]
235
- }),
236
- {}
237
- ) : {};
238
- const WalletConnectProvider = (await import("@walletconnect/ethereum-provider")).default;
239
- __privateSet(this, _provider, new WalletConnectProvider({
240
- ...this.options,
241
- chainId,
242
- rpc: { ...rpc, ...this.options?.rpc }
243
- }));
244
- return __privateGet(this, _provider);
245
- }
128
+ async getProvider({ chainId } = {}) {
129
+ if (!__privateGet(this, _provider))
130
+ await __privateMethod(this, _createProvider, createProvider_fn).call(this);
131
+ if (chainId)
132
+ await this.switchChain(chainId);
246
133
  return __privateGet(this, _provider);
247
134
  }
248
135
  async getSigner({ chainId } = {}) {
@@ -250,110 +137,165 @@ var WalletConnectConnector = class extends Connector {
250
137
  this.getProvider({ chainId }),
251
138
  this.getAccount()
252
139
  ]);
253
- let provider_ = provider;
254
- if (this.version === "2") {
255
- const chainId_ = await this.getChainId();
256
- provider_ = {
257
- ...provider,
258
- async request(args) {
259
- return await provider.request(
260
- args,
261
- `${defaultV2Config.namespace}:${chainId ?? chainId_}`
262
- );
263
- }
264
- };
265
- }
266
- return new providers.Web3Provider(provider_, chainId).getSigner(account);
140
+ return new providers.Web3Provider(provider, chainId).getSigner(account);
267
141
  }
268
142
  async isAuthorized() {
269
143
  try {
270
- const [account, isChainsAuthorized] = await Promise.all([
144
+ const [account, provider] = await Promise.all([
271
145
  this.getAccount(),
272
- __privateMethod(this, _isChainsAuthorized, isChainsAuthorized_fn).call(this)
146
+ this.getProvider()
273
147
  ]);
274
- return !!account && isChainsAuthorized;
148
+ const isChainsStale = __privateMethod(this, _isChainsStale, isChainsStale_fn).call(this);
149
+ if (!account)
150
+ return false;
151
+ if (isChainsStale && provider.session) {
152
+ try {
153
+ await provider.disconnect();
154
+ } catch {
155
+ }
156
+ return false;
157
+ }
158
+ return true;
275
159
  } catch {
276
160
  return false;
277
161
  }
278
162
  }
163
+ async switchChain(chainId) {
164
+ const chain = this.chains.find((chain2) => chain2.id === chainId);
165
+ if (!chain)
166
+ throw new SwitchChainError(new Error("chain not found on connector."));
167
+ try {
168
+ const provider = await this.getProvider();
169
+ const namespaceChains = __privateMethod(this, _getNamespaceChainsIds, getNamespaceChainsIds_fn).call(this);
170
+ const namespaceMethods = __privateMethod(this, _getNamespaceMethods, getNamespaceMethods_fn).call(this);
171
+ const isChainApproved = namespaceChains.includes(chainId);
172
+ if (!isChainApproved && namespaceMethods.includes(ADD_ETH_CHAIN_METHOD)) {
173
+ await provider.request({
174
+ method: ADD_ETH_CHAIN_METHOD,
175
+ params: [
176
+ {
177
+ chainId: hexValue(chain.id),
178
+ blockExplorerUrls: [chain.blockExplorers?.default],
179
+ chainName: chain.name,
180
+ nativeCurrency: chain.nativeCurrency,
181
+ rpcUrls: [...chain.rpcUrls.default.http]
182
+ }
183
+ ]
184
+ });
185
+ const requestedChains = __privateMethod(this, _getRequestedChainsIds, getRequestedChainsIds_fn).call(this);
186
+ requestedChains.push(chainId);
187
+ __privateMethod(this, _setRequestedChainsIds, setRequestedChainsIds_fn).call(this, requestedChains);
188
+ }
189
+ await provider.request({
190
+ method: "wallet_switchEthereumChain",
191
+ params: [{ chainId: hexValue(chainId) }]
192
+ });
193
+ return chain;
194
+ } catch (error) {
195
+ const message = typeof error === "string" ? error : error?.message;
196
+ if (/user rejected request/i.test(message)) {
197
+ throw new UserRejectedRequestError(error);
198
+ }
199
+ throw new SwitchChainError(error);
200
+ }
201
+ }
279
202
  };
280
203
  _provider = new WeakMap();
281
- _initUniversalProviderPromise = new WeakMap();
282
- _web3Modal = new WeakMap();
283
- _createWeb3Modal = new WeakSet();
284
- createWeb3Modal_fn = async function() {
285
- const { Web3Modal } = await import("@web3modal/standalone");
286
- const { version } = this.options;
287
- __privateSet(this, _web3Modal, new Web3Modal({
288
- walletConnectVersion: version === "2" ? 2 : 1,
289
- projectId: version === "2" ? this.options.projectId : "",
290
- standaloneChains: this.namespacedChains
291
- }));
292
- };
293
- _initUniversalProvider = new WeakSet();
294
- initUniversalProvider_fn = async function() {
295
- const WalletConnectProvider = (await import("@walletconnect/universal-provider")).default;
296
- if (typeof WalletConnectProvider?.init === "function") {
297
- __privateSet(this, _provider, await WalletConnectProvider.init(
298
- this.options
299
- ));
204
+ _initProviderPromise = new WeakMap();
205
+ _createProvider = new WeakSet();
206
+ createProvider_fn = async function() {
207
+ if (!__privateGet(this, _initProviderPromise) && typeof window !== "undefined") {
208
+ __privateSet(this, _initProviderPromise, __privateMethod(this, _initProvider, initProvider_fn).call(this));
300
209
  }
210
+ return __privateGet(this, _initProviderPromise);
301
211
  };
302
- _createUniversalProvider = new WeakSet();
303
- createUniversalProvider_fn = async function() {
304
- if (!__privateGet(this, _initUniversalProviderPromise)) {
305
- __privateSet(this, _initUniversalProviderPromise, __privateMethod(this, _initUniversalProvider, initUniversalProvider_fn).call(this));
212
+ _initProvider = new WeakSet();
213
+ initProvider_fn = async function() {
214
+ const {
215
+ default: EthereumProvider,
216
+ OPTIONAL_EVENTS,
217
+ OPTIONAL_METHODS
218
+ } = await import("@walletconnect/ethereum-provider");
219
+ const [defaultChain, ...optionalChains] = this.chains.map(({ id }) => id);
220
+ if (defaultChain) {
221
+ const { projectId, showQrModal } = this.options;
222
+ __privateSet(this, _provider, await EthereumProvider.init({
223
+ showQrModal,
224
+ projectId,
225
+ optionalMethods: OPTIONAL_METHODS,
226
+ optionalEvents: OPTIONAL_EVENTS,
227
+ chains: [defaultChain],
228
+ optionalChains,
229
+ rpcMap: Object.fromEntries(
230
+ this.chains.map((chain) => [
231
+ chain.id,
232
+ chain.rpcUrls.default.http[0]
233
+ ])
234
+ )
235
+ }));
306
236
  }
307
- return __privateGet(this, _initUniversalProviderPromise);
308
237
  };
309
- _isChainsAuthorized = new WeakSet();
310
- isChainsAuthorized_fn = async function() {
311
- const provider = await this.getProvider();
312
- if (this.version === "1")
313
- return true;
314
- const providerChains = provider.namespaces?.[defaultV2Config.namespace]?.chains || [];
315
- const authorizedChainIds = providerChains.map(
238
+ _isChainsStale = new WeakSet();
239
+ isChainsStale_fn = function() {
240
+ const namespaceMethods = __privateMethod(this, _getNamespaceMethods, getNamespaceMethods_fn).call(this);
241
+ if (namespaceMethods.includes(ADD_ETH_CHAIN_METHOD))
242
+ return false;
243
+ if (!this.options.isNewChainsStale)
244
+ return false;
245
+ const requestedChains = __privateMethod(this, _getRequestedChainsIds, getRequestedChainsIds_fn).call(this);
246
+ const connectorChains = this.chains.map(({ id }) => id);
247
+ const namespaceChains = __privateMethod(this, _getNamespaceChainsIds, getNamespaceChainsIds_fn).call(this);
248
+ if (namespaceChains.length && !namespaceChains.some((id) => connectorChains.includes(id)))
249
+ return false;
250
+ return !connectorChains.every((id) => requestedChains.includes(id));
251
+ };
252
+ _setupListeners = new WeakSet();
253
+ setupListeners_fn = function() {
254
+ if (!__privateGet(this, _provider))
255
+ return;
256
+ __privateMethod(this, _removeListeners, removeListeners_fn).call(this);
257
+ __privateGet(this, _provider).on("accountsChanged", this.onAccountsChanged);
258
+ __privateGet(this, _provider).on("chainChanged", this.onChainChanged);
259
+ __privateGet(this, _provider).on("disconnect", this.onDisconnect);
260
+ __privateGet(this, _provider).on("session_delete", this.onDisconnect);
261
+ __privateGet(this, _provider).on("display_uri", this.onDisplayUri);
262
+ __privateGet(this, _provider).on("connect", this.onConnect);
263
+ };
264
+ _removeListeners = new WeakSet();
265
+ removeListeners_fn = function() {
266
+ if (!__privateGet(this, _provider))
267
+ return;
268
+ __privateGet(this, _provider).removeListener("accountsChanged", this.onAccountsChanged);
269
+ __privateGet(this, _provider).removeListener("chainChanged", this.onChainChanged);
270
+ __privateGet(this, _provider).removeListener("disconnect", this.onDisconnect);
271
+ __privateGet(this, _provider).removeListener("session_delete", this.onDisconnect);
272
+ __privateGet(this, _provider).removeListener("display_uri", this.onDisplayUri);
273
+ __privateGet(this, _provider).removeListener("connect", this.onConnect);
274
+ };
275
+ _setRequestedChainsIds = new WeakSet();
276
+ setRequestedChainsIds_fn = function(chains) {
277
+ localStorage.setItem(REQUESTED_CHAINS_KEY, JSON.stringify(chains));
278
+ };
279
+ _getRequestedChainsIds = new WeakSet();
280
+ getRequestedChainsIds_fn = function() {
281
+ const data = localStorage.getItem(REQUESTED_CHAINS_KEY);
282
+ return data ? JSON.parse(data) : [];
283
+ };
284
+ _getNamespaceChainsIds = new WeakSet();
285
+ getNamespaceChainsIds_fn = function() {
286
+ if (!__privateGet(this, _provider))
287
+ return [];
288
+ const chainIds = __privateGet(this, _provider).session?.namespaces[NAMESPACE]?.chains?.map(
316
289
  (chain) => parseInt(chain.split(":")[1] || "")
317
290
  );
318
- return !this.chains.some(({ id }) => !authorizedChainIds.includes(id));
291
+ return chainIds ?? [];
319
292
  };
320
- _switchChain = new WeakSet();
321
- switchChain_fn = async function(chainId) {
322
- const provider = await this.getProvider();
323
- const id = hexValue(chainId);
324
- try {
325
- await Promise.race([
326
- provider.request({
327
- method: "wallet_switchEthereumChain",
328
- params: [{ chainId: id }]
329
- }),
330
- new Promise(
331
- (res) => this.on("change", ({ chain }) => {
332
- if (chain?.id === chainId)
333
- res(chainId);
334
- })
335
- )
336
- ]);
337
- if (this.version === "2") {
338
- ;
339
- provider.setDefaultChain(
340
- `${defaultV2Config.namespace}:${chainId}`
341
- );
342
- this.onChainChanged(chainId);
343
- }
344
- return this.chains.find((x) => x.id === chainId) ?? {
345
- id: chainId,
346
- name: `Chain ${id}`,
347
- network: `${id}`,
348
- nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
349
- rpcUrls: { default: { http: [""] }, public: { http: [""] } }
350
- };
351
- } catch (error) {
352
- const message = typeof error === "string" ? error : error?.message;
353
- if (/user rejected request/i.test(message))
354
- throw new UserRejectedRequestError(error);
355
- throw new SwitchChainError(error);
356
- }
293
+ _getNamespaceMethods = new WeakSet();
294
+ getNamespaceMethods_fn = function() {
295
+ if (!__privateGet(this, _provider))
296
+ return [];
297
+ const methods = __privateGet(this, _provider).session?.namespaces[NAMESPACE]?.methods;
298
+ return methods ?? [];
357
299
  };
358
300
  export {
359
301
  WalletConnectConnector
@@ -0,0 +1,45 @@
1
+ import { Chain } from '@wagmi/core/chains';
2
+ import WalletConnectProvider from '@walletconnect/legacy-provider';
3
+ import { providers } from 'ethers';
4
+ import { C as Connector } from './base-84a689bb.js';
5
+ import '@wagmi/core';
6
+ import 'eventemitter3';
7
+
8
+ type WalletConnectOptions = ConstructorParameters<typeof WalletConnectProvider>[0];
9
+ type WalletConnectSigner = providers.JsonRpcSigner;
10
+ declare class WalletConnectLegacyConnector extends Connector<WalletConnectProvider, WalletConnectOptions, WalletConnectSigner> {
11
+ #private;
12
+ readonly id = "walletConnectLegacy";
13
+ readonly name = "WalletConnectLegacy";
14
+ readonly ready = true;
15
+ constructor(config: {
16
+ chains?: Chain[];
17
+ options: WalletConnectOptions;
18
+ });
19
+ connect({ chainId }?: {
20
+ chainId?: number;
21
+ }): Promise<{
22
+ account: `0x${string}`;
23
+ chain: {
24
+ id: number;
25
+ unsupported: boolean;
26
+ };
27
+ provider: providers.Web3Provider;
28
+ }>;
29
+ disconnect(): Promise<void>;
30
+ getAccount(): Promise<`0x${string}`>;
31
+ getChainId(): Promise<number>;
32
+ getProvider({ chainId, create, }?: {
33
+ chainId?: number;
34
+ create?: boolean;
35
+ }): Promise<WalletConnectProvider>;
36
+ getSigner({ chainId }?: {
37
+ chainId?: number;
38
+ }): Promise<providers.JsonRpcSigner>;
39
+ isAuthorized(): Promise<boolean>;
40
+ protected onAccountsChanged: (accounts: string[]) => void;
41
+ protected onChainChanged: (chainId: number | string) => void;
42
+ protected onDisconnect: () => void;
43
+ }
44
+
45
+ export { WalletConnectLegacyConnector };
@@ -0,0 +1,172 @@
1
+ import {
2
+ Connector,
3
+ __privateAdd,
4
+ __privateGet,
5
+ __privateMethod,
6
+ __privateSet,
7
+ __publicField
8
+ } from "./chunk-5NCTPR6C.js";
9
+
10
+ // src/walletConnectLegacy.ts
11
+ import {
12
+ SwitchChainError,
13
+ UserRejectedRequestError,
14
+ getClient,
15
+ normalizeChainId
16
+ } from "@wagmi/core";
17
+ import { providers } from "ethers";
18
+ import { getAddress, hexValue } from "ethers/lib/utils.js";
19
+ var switchChainAllowedRegex = /(imtoken|metamask|rainbow|trust wallet)/i;
20
+ var _provider, _switchChain, switchChain_fn;
21
+ var WalletConnectLegacyConnector = class extends Connector {
22
+ constructor(config) {
23
+ super(config);
24
+ __privateAdd(this, _switchChain);
25
+ __publicField(this, "id", "walletConnectLegacy");
26
+ __publicField(this, "name", "WalletConnectLegacy");
27
+ __publicField(this, "ready", true);
28
+ __privateAdd(this, _provider, void 0);
29
+ __publicField(this, "onAccountsChanged", (accounts) => {
30
+ if (accounts.length === 0)
31
+ this.emit("disconnect");
32
+ else
33
+ this.emit("change", { account: getAddress(accounts[0]) });
34
+ });
35
+ __publicField(this, "onChainChanged", (chainId) => {
36
+ const id = normalizeChainId(chainId);
37
+ const unsupported = this.isChainUnsupported(id);
38
+ this.emit("change", { chain: { id, unsupported } });
39
+ });
40
+ __publicField(this, "onDisconnect", () => {
41
+ this.emit("disconnect");
42
+ });
43
+ }
44
+ async connect({ chainId } = {}) {
45
+ try {
46
+ let targetChainId = chainId;
47
+ if (!targetChainId) {
48
+ const lastUsedChainId = getClient().lastUsedChainId;
49
+ if (lastUsedChainId && !this.isChainUnsupported(lastUsedChainId))
50
+ targetChainId = lastUsedChainId;
51
+ }
52
+ const provider = await this.getProvider({
53
+ chainId: targetChainId,
54
+ create: true
55
+ });
56
+ provider.on("accountsChanged", this.onAccountsChanged);
57
+ provider.on("chainChanged", this.onChainChanged);
58
+ provider.on("disconnect", this.onDisconnect);
59
+ setTimeout(() => this.emit("message", { type: "connecting" }), 0);
60
+ const accounts = await provider.enable();
61
+ const account = getAddress(accounts[0]);
62
+ const id = await this.getChainId();
63
+ const unsupported = this.isChainUnsupported(id);
64
+ const walletName = provider.connector?.peerMeta?.name ?? "";
65
+ if (switchChainAllowedRegex.test(walletName))
66
+ this.switchChain = __privateMethod(this, _switchChain, switchChain_fn);
67
+ return {
68
+ account,
69
+ chain: { id, unsupported },
70
+ provider: new providers.Web3Provider(
71
+ provider
72
+ )
73
+ };
74
+ } catch (error) {
75
+ if (/user closed modal/i.test(error.message))
76
+ throw new UserRejectedRequestError(error);
77
+ throw error;
78
+ }
79
+ }
80
+ async disconnect() {
81
+ const provider = await this.getProvider();
82
+ await provider.disconnect();
83
+ provider.removeListener("accountsChanged", this.onAccountsChanged);
84
+ provider.removeListener("chainChanged", this.onChainChanged);
85
+ provider.removeListener("disconnect", this.onDisconnect);
86
+ typeof localStorage !== "undefined" && localStorage.removeItem("walletconnect");
87
+ }
88
+ async getAccount() {
89
+ const provider = await this.getProvider();
90
+ const accounts = provider.accounts;
91
+ return getAddress(accounts[0]);
92
+ }
93
+ async getChainId() {
94
+ const provider = await this.getProvider();
95
+ const chainId = normalizeChainId(provider.chainId);
96
+ return chainId;
97
+ }
98
+ async getProvider({
99
+ chainId,
100
+ create
101
+ } = {}) {
102
+ if (!__privateGet(this, _provider) || chainId || create) {
103
+ const rpc = !this.options?.infuraId ? this.chains.reduce(
104
+ (rpc2, chain) => ({
105
+ ...rpc2,
106
+ [chain.id]: chain.rpcUrls.default.http[0]
107
+ }),
108
+ {}
109
+ ) : {};
110
+ const WalletConnectProvider = (await import("@walletconnect/legacy-provider")).default;
111
+ __privateSet(this, _provider, new WalletConnectProvider({
112
+ ...this.options,
113
+ chainId,
114
+ rpc: { ...rpc, ...this.options?.rpc }
115
+ }));
116
+ }
117
+ return __privateGet(this, _provider);
118
+ }
119
+ async getSigner({ chainId } = {}) {
120
+ const [provider, account] = await Promise.all([
121
+ this.getProvider({ chainId }),
122
+ this.getAccount()
123
+ ]);
124
+ return new providers.Web3Provider(
125
+ provider,
126
+ chainId
127
+ ).getSigner(account);
128
+ }
129
+ async isAuthorized() {
130
+ try {
131
+ const account = await this.getAccount();
132
+ return !!account;
133
+ } catch {
134
+ return false;
135
+ }
136
+ }
137
+ };
138
+ _provider = new WeakMap();
139
+ _switchChain = new WeakSet();
140
+ switchChain_fn = async function(chainId) {
141
+ const provider = await this.getProvider();
142
+ const id = hexValue(chainId);
143
+ try {
144
+ await Promise.race([
145
+ provider.request({
146
+ method: "wallet_switchEthereumChain",
147
+ params: [{ chainId: id }]
148
+ }),
149
+ new Promise(
150
+ (res) => this.on("change", ({ chain }) => {
151
+ if (chain?.id === chainId)
152
+ res(chainId);
153
+ })
154
+ )
155
+ ]);
156
+ return this.chains.find((x) => x.id === chainId) ?? {
157
+ id: chainId,
158
+ name: `Chain ${id}`,
159
+ network: `${id}`,
160
+ nativeCurrency: { name: "Ether", decimals: 18, symbol: "ETH" },
161
+ rpcUrls: { default: { http: [""] }, public: { http: [""] } }
162
+ };
163
+ } catch (error) {
164
+ const message = typeof error === "string" ? error : error?.message;
165
+ if (/user rejected request/i.test(message))
166
+ throw new UserRejectedRequestError(error);
167
+ throw new SwitchChainError(error);
168
+ }
169
+ };
170
+ export {
171
+ WalletConnectLegacyConnector
172
+ };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@wagmi/connectors",
3
3
  "description": "A collection of connectors for wagmi",
4
4
  "license": "MIT",
5
- "version": "0.2.7",
5
+ "version": "0.3.0",
6
6
  "peerDependencies": {
7
7
  "@wagmi/core": ">=0.9.x",
8
8
  "ethers": ">=5.5.1 <6",
@@ -19,11 +19,10 @@
19
19
  "dependencies": {
20
20
  "@coinbase/wallet-sdk": "^3.5.4",
21
21
  "@ledgerhq/connect-kit-loader": "^1.0.1",
22
- "@walletconnect/ethereum-provider": "^1.8.0",
23
- "@walletconnect/universal-provider": "2.3.3",
22
+ "@walletconnect/ethereum-provider": "^2.4.6",
23
+ "@walletconnect/legacy-provider": "^2.0.0",
24
24
  "@safe-global/safe-apps-provider": "^0.15.2",
25
25
  "@safe-global/safe-apps-sdk": "^7.9.0",
26
- "@web3modal/standalone": "^2.1.1",
27
26
  "abitype": "^0.3.0",
28
27
  "eventemitter3": "^4.0.7"
29
28
  },
@@ -67,6 +66,10 @@
67
66
  "types": "./dist/walletConnect.d.ts",
68
67
  "default": "./dist/walletConnect.js"
69
68
  },
69
+ "./walletConnectLegacy": {
70
+ "types": "./dist/walletConnectLegacy.d.ts",
71
+ "default": "./dist/walletConnectLegacy.js"
72
+ },
70
73
  "./package.json": "./package.json"
71
74
  },
72
75
  "files": [
@@ -77,6 +80,7 @@
77
80
  "/mock",
78
81
  "/safe",
79
82
  "/walletConnect",
83
+ "/walletConnectLegacy",
80
84
  "/dist"
81
85
  ],
82
86
  "sideEffects": false,
@@ -0,0 +1,4 @@
1
+ {
2
+ "type": "module",
3
+ "main": "../dist/walletConnectLegacy.js"
4
+ }