@getpara/evm-wallet-connectors 2.0.0-alpha.67 → 2.0.0-alpha.69

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/README.md ADDED
@@ -0,0 +1,20 @@
1
+ https://www.npmjs.com/package/@getpara/evm-wallet-connectors
2
+
3
+ The package is used with Para's React SDK Lite to enable external EVM wallet connections. Para automatically manages the Wagmi provider internally when you configure external wallet support.
4
+
5
+ ###Key Features
6
+
7
+ - Wagmi Integration: Powered by Wagmi, the popular React hooks library for Ethereum
8
+ - Automatic Setup: Para handles all Wagmi provider configuration internally
9
+ - Unified Configuration: Configure chains and settings through Para's `externalWalletConfig`
10
+ - All Wagmi Hooks Available: Use any Wagmi hook alongside Para hooks
11
+
12
+ ###Prerequisites
13
+
14
+ To use Para, you need an API key. This key authenticates your requests to Para services and is essential for integration.
15
+
16
+ Don't have an API key yet? Request access to the [Developer Portal](https://developer.getpara.com/) to create API keys, manage billing, teams, and more.
17
+
18
+ ###Learn more
19
+
20
+ For more information on Para’s EVM Wallet Connectors visit the [Para Docs](https://docs.getpara.com/v2/react/guides/external-wallets/evm-lite#evm-wallets-with-react-sdk-lite)
@@ -0,0 +1,63 @@
1
+ import type { Compute, ExactPartial, Omit } from '@wagmi/core/internal';
2
+ import type { EthereumProvider } from '@walletconnect/ethereum-provider';
3
+ import { type Address, type ProviderConnectInfo } from 'viem';
4
+ type EthereumProviderOptions = Parameters<(typeof EthereumProvider)['init']>[0];
5
+ export type WalletConnectParameters = Compute<{
6
+ /**
7
+ * If a new chain is added to a previously existing configured connector `chains`, this flag
8
+ * will determine if that chain should be considered as stale. A stale chain is a chain that
9
+ * WalletConnect has yet to establish a relationship with (e.g. the user has not approved or
10
+ * rejected the chain).
11
+ *
12
+ * This flag mainly affects the behavior when a wallet does not support dynamic chain authorization
13
+ * with WalletConnect v2.
14
+ *
15
+ * If `true` (default), the new chain will be treated as a stale chain. If the user
16
+ * has yet to establish a relationship (approved/rejected) with this chain in their WalletConnect
17
+ * session, the connector will disconnect upon the dapp auto-connecting, and the user will have to
18
+ * reconnect to the dapp (revalidate the chain) in order to approve the newly added chain.
19
+ * This is the default behavior to avoid an unexpected error upon switching chains which may
20
+ * be a confusing user experience (e.g. the user will not know they have to reconnect
21
+ * unless the dapp handles these types of errors).
22
+ *
23
+ * If `false`, the new chain will be treated as a potentially valid chain. This means that if the user
24
+ * has yet to establish a relationship with the chain in their WalletConnect session, wagmi will successfully
25
+ * auto-connect the user. This comes with the trade-off that the connector will throw an error
26
+ * when attempting to switch to the unapproved chain if the wallet does not support dynamic session updates.
27
+ * This may be useful in cases where a dapp constantly
28
+ * modifies their configured chains, and they do not want to disconnect the user upon
29
+ * auto-connecting. If the user decides to switch to the unapproved chain, it is important that the
30
+ * dapp handles this error and prompts the user to reconnect to the dapp in order to approve
31
+ * the newly added chain.
32
+ *
33
+ * @default true
34
+ */
35
+ isNewChainsStale?: boolean;
36
+ } & Omit<EthereumProviderOptions, 'chains' | 'events' | 'optionalChains' | 'optionalEvents' | 'optionalMethods' | 'methods' | 'rpcMap' | 'showQrModal'> & ExactPartial<Pick<EthereumProviderOptions, 'showQrModal'>>>;
37
+ type ConnectParams = {
38
+ chainId?: number | undefined;
39
+ isReconnecting?: boolean | undefined;
40
+ pairingTopic?: string | undefined;
41
+ };
42
+ export declare function walletConnect(parameters: WalletConnectParameters): import("@wagmi/core").CreateConnectorFn<import("@walletconnect/ethereum-provider").default, {
43
+ connect(parameters: ConnectParams): Promise<{
44
+ accounts: readonly Address[];
45
+ chainId: number;
46
+ }>;
47
+ getNamespaceChainsIds(): number[];
48
+ getRequestedChainsIds(): Promise<number[]>;
49
+ isChainsStale(): Promise<boolean>;
50
+ onConnect(connectInfo: ProviderConnectInfo): void;
51
+ onDisplayUri(uri: string): void;
52
+ onSessionDelete(data: {
53
+ topic: string;
54
+ }): void;
55
+ setRequestedChainsIds(chains: number[]): void;
56
+ requestedChainsStorageKey: `${string}.requestedChains`;
57
+ }, {
58
+ [x: `${string}.requestedChains`]: number[];
59
+ }>;
60
+ export declare namespace walletConnect {
61
+ var type: "walletConnect";
62
+ }
63
+ export {};
@@ -0,0 +1,366 @@
1
+ "use client";
2
+ import {
3
+ __async,
4
+ __objRest,
5
+ __spreadProps,
6
+ __spreadValues
7
+ } from "../chunk-MMUBH76A.js";
8
+ import {
9
+ ChainNotConfiguredError,
10
+ ProviderNotFoundError,
11
+ createConnector,
12
+ extractRpcUrls
13
+ } from "@wagmi/core";
14
+ import {
15
+ SwitchChainError,
16
+ UserRejectedRequestError,
17
+ getAddress,
18
+ numberToHex
19
+ } from "viem";
20
+ walletConnect.type = "walletConnect";
21
+ function walletConnect(parameters) {
22
+ var _a;
23
+ const isNewChainsStale = (_a = parameters.isNewChainsStale) != null ? _a : true;
24
+ let provider_;
25
+ let providerPromise;
26
+ const NAMESPACE = "eip155";
27
+ let accountsChanged;
28
+ let chainChanged;
29
+ let connect;
30
+ let displayUri;
31
+ let sessionDelete;
32
+ let disconnect;
33
+ return createConnector((config) => ({
34
+ id: "walletConnect",
35
+ name: "WalletConnect",
36
+ type: walletConnect.type,
37
+ setup() {
38
+ return __async(this, null, function* () {
39
+ const provider = yield this.getProvider().catch(() => null);
40
+ if (!provider) return;
41
+ if (!connect) {
42
+ connect = this.onConnect.bind(this);
43
+ provider.on("connect", connect);
44
+ }
45
+ if (!sessionDelete) {
46
+ sessionDelete = this.onSessionDelete.bind(this);
47
+ provider.on("session_delete", sessionDelete);
48
+ }
49
+ });
50
+ },
51
+ connect() {
52
+ return __async(this, arguments, function* (_b = {}) {
53
+ var _c = _b, { chainId } = _c, rest = __objRest(_c, ["chainId"]);
54
+ var _a3, _b2, _c2;
55
+ try {
56
+ const provider = yield this.getProvider();
57
+ if (!provider) throw new ProviderNotFoundError();
58
+ if (!displayUri) {
59
+ displayUri = this.onDisplayUri;
60
+ provider.on("display_uri", displayUri);
61
+ }
62
+ let targetChainId = chainId;
63
+ if (!targetChainId) {
64
+ const state = (_b2 = yield (_a3 = config.storage) == null ? void 0 : _a3.getItem("state")) != null ? _b2 : {};
65
+ const isChainSupported = config.chains.some((x) => x.id === state.chainId);
66
+ if (isChainSupported) targetChainId = state.chainId;
67
+ else targetChainId = (_c2 = config.chains[0]) == null ? void 0 : _c2.id;
68
+ }
69
+ if (!targetChainId) throw new Error("No chains found on connector.");
70
+ const isChainsStale = yield this.isChainsStale();
71
+ if (provider.session && isChainsStale) yield provider.disconnect();
72
+ if (!provider.session || isChainsStale) {
73
+ const optionalChains = config.chains.filter((chain) => chain.id !== targetChainId).map((optionalChain) => optionalChain.id);
74
+ yield provider.connect(__spreadValues({
75
+ optionalChains: [targetChainId, ...optionalChains]
76
+ }, "pairingTopic" in rest ? { pairingTopic: rest.pairingTopic } : {}));
77
+ this.setRequestedChainsIds(config.chains.map((x) => x.id));
78
+ }
79
+ const accounts = (yield provider.enable()).map((x) => getAddress(x));
80
+ const currentChainId = yield this.getChainId();
81
+ if (displayUri) {
82
+ provider.removeListener("display_uri", displayUri);
83
+ displayUri = void 0;
84
+ }
85
+ if (connect) {
86
+ provider.removeListener("connect", connect);
87
+ connect = void 0;
88
+ }
89
+ if (!accountsChanged) {
90
+ accountsChanged = this.onAccountsChanged.bind(this);
91
+ provider.on("accountsChanged", accountsChanged);
92
+ }
93
+ if (!chainChanged) {
94
+ chainChanged = this.onChainChanged.bind(this);
95
+ provider.on("chainChanged", chainChanged);
96
+ }
97
+ if (!disconnect) {
98
+ disconnect = this.onDisconnect.bind(this);
99
+ provider.on("disconnect", disconnect);
100
+ }
101
+ if (!sessionDelete) {
102
+ sessionDelete = this.onSessionDelete.bind(this);
103
+ provider.on("session_delete", sessionDelete);
104
+ }
105
+ return { accounts, chainId: currentChainId };
106
+ } catch (error) {
107
+ if (/(user rejected|connection request reset)/i.test(error == null ? void 0 : error.message)) {
108
+ throw new UserRejectedRequestError(error);
109
+ }
110
+ throw error;
111
+ }
112
+ });
113
+ },
114
+ disconnect() {
115
+ return __async(this, null, function* () {
116
+ const provider = yield this.getProvider();
117
+ try {
118
+ yield provider == null ? void 0 : provider.disconnect();
119
+ } catch (error) {
120
+ if (!/No matching key/i.test(error.message)) throw error;
121
+ } finally {
122
+ if (chainChanged) {
123
+ provider == null ? void 0 : provider.removeListener("chainChanged", chainChanged);
124
+ chainChanged = void 0;
125
+ }
126
+ if (disconnect) {
127
+ provider == null ? void 0 : provider.removeListener("disconnect", disconnect);
128
+ disconnect = void 0;
129
+ }
130
+ if (!connect) {
131
+ connect = this.onConnect.bind(this);
132
+ provider == null ? void 0 : provider.on("connect", connect);
133
+ }
134
+ if (accountsChanged) {
135
+ provider == null ? void 0 : provider.removeListener("accountsChanged", accountsChanged);
136
+ accountsChanged = void 0;
137
+ }
138
+ if (sessionDelete) {
139
+ provider == null ? void 0 : provider.removeListener("session_delete", sessionDelete);
140
+ sessionDelete = void 0;
141
+ }
142
+ this.setRequestedChainsIds([]);
143
+ }
144
+ });
145
+ },
146
+ getAccounts() {
147
+ return __async(this, null, function* () {
148
+ const provider = yield this.getProvider();
149
+ return provider.accounts.map((x) => getAddress(x));
150
+ });
151
+ },
152
+ getProvider() {
153
+ return __async(this, arguments, function* ({ chainId } = {}) {
154
+ var _a3;
155
+ function initProvider() {
156
+ return __async(this, null, function* () {
157
+ var _a4;
158
+ const optionalChains = config.chains.map((x) => x.id);
159
+ if (!optionalChains.length) return;
160
+ const { EthereumProvider } = yield import("@walletconnect/ethereum-provider");
161
+ return yield EthereumProvider.init(__spreadProps(__spreadValues({}, parameters), {
162
+ disableProviderPing: true,
163
+ optionalChains,
164
+ projectId: parameters.projectId,
165
+ rpcMap: Object.fromEntries(
166
+ config.chains.map((chain) => {
167
+ const [url] = extractRpcUrls({
168
+ chain,
169
+ transports: config.transports
170
+ });
171
+ return [chain.id, url];
172
+ })
173
+ ),
174
+ showQrModal: (_a4 = parameters.showQrModal) != null ? _a4 : true
175
+ }));
176
+ });
177
+ }
178
+ if (!provider_) {
179
+ if (!providerPromise) providerPromise = initProvider();
180
+ provider_ = yield providerPromise;
181
+ provider_ == null ? void 0 : provider_.events.setMaxListeners(Number.POSITIVE_INFINITY);
182
+ }
183
+ if (chainId) yield (_a3 = this.switchChain) == null ? void 0 : _a3.call(this, { chainId });
184
+ return provider_;
185
+ });
186
+ },
187
+ getChainId() {
188
+ return __async(this, null, function* () {
189
+ const provider = yield this.getProvider();
190
+ return provider.chainId;
191
+ });
192
+ },
193
+ isAuthorized() {
194
+ return __async(this, null, function* () {
195
+ try {
196
+ const [accounts, provider] = yield Promise.all([this.getAccounts(), this.getProvider()]);
197
+ if (!accounts.length) return false;
198
+ const isChainsStale = yield this.isChainsStale();
199
+ if (isChainsStale && provider.session) {
200
+ yield provider.disconnect().catch(() => {
201
+ });
202
+ return false;
203
+ }
204
+ return true;
205
+ } catch (e) {
206
+ return false;
207
+ }
208
+ });
209
+ },
210
+ switchChain(_0) {
211
+ return __async(this, arguments, function* ({ addEthereumChainParameter, chainId }) {
212
+ var _a3, _b, _c, _d, _e;
213
+ const provider = yield this.getProvider();
214
+ if (!provider) throw new ProviderNotFoundError();
215
+ const chain = config.chains.find((x) => x.id === chainId);
216
+ if (!chain) throw new SwitchChainError(new ChainNotConfiguredError());
217
+ try {
218
+ yield Promise.all([
219
+ new Promise((resolve) => {
220
+ const listener = ({ chainId: currentChainId }) => {
221
+ if (currentChainId === chainId) {
222
+ config.emitter.off("change", listener);
223
+ resolve();
224
+ }
225
+ };
226
+ config.emitter.on("change", listener);
227
+ }),
228
+ provider.request({
229
+ method: "wallet_switchEthereumChain",
230
+ params: [{ chainId: numberToHex(chainId) }]
231
+ })
232
+ ]);
233
+ const requestedChains = yield this.getRequestedChainsIds();
234
+ this.setRequestedChainsIds([...requestedChains, chainId]);
235
+ return chain;
236
+ } catch (err) {
237
+ const error = err;
238
+ if (/(user rejected)/i.test(error.message)) throw new UserRejectedRequestError(error);
239
+ try {
240
+ let blockExplorerUrls;
241
+ if (addEthereumChainParameter == null ? void 0 : addEthereumChainParameter.blockExplorerUrls) blockExplorerUrls = addEthereumChainParameter.blockExplorerUrls;
242
+ else blockExplorerUrls = ((_a3 = chain.blockExplorers) == null ? void 0 : _a3.default.url) ? [(_b = chain.blockExplorers) == null ? void 0 : _b.default.url] : [];
243
+ let rpcUrls;
244
+ if ((_c = addEthereumChainParameter == null ? void 0 : addEthereumChainParameter.rpcUrls) == null ? void 0 : _c.length) rpcUrls = addEthereumChainParameter.rpcUrls;
245
+ else rpcUrls = [...chain.rpcUrls.default.http];
246
+ const addEthereumChain = {
247
+ blockExplorerUrls,
248
+ chainId: numberToHex(chainId),
249
+ chainName: (_d = addEthereumChainParameter == null ? void 0 : addEthereumChainParameter.chainName) != null ? _d : chain.name,
250
+ iconUrls: addEthereumChainParameter == null ? void 0 : addEthereumChainParameter.iconUrls,
251
+ nativeCurrency: (_e = addEthereumChainParameter == null ? void 0 : addEthereumChainParameter.nativeCurrency) != null ? _e : chain.nativeCurrency,
252
+ rpcUrls
253
+ };
254
+ yield provider.request({
255
+ method: "wallet_addEthereumChain",
256
+ params: [addEthereumChain]
257
+ });
258
+ const requestedChains = yield this.getRequestedChainsIds();
259
+ this.setRequestedChainsIds([...requestedChains, chainId]);
260
+ return chain;
261
+ } catch (error2) {
262
+ throw new UserRejectedRequestError(error2);
263
+ }
264
+ }
265
+ });
266
+ },
267
+ onAccountsChanged(accounts) {
268
+ if (accounts.length === 0) this.onDisconnect();
269
+ else
270
+ config.emitter.emit("change", {
271
+ accounts: accounts.map((x) => getAddress(x))
272
+ });
273
+ },
274
+ onChainChanged(chain) {
275
+ const chainId = Number(chain);
276
+ config.emitter.emit("change", { chainId });
277
+ },
278
+ onConnect(connectInfo) {
279
+ return __async(this, null, function* () {
280
+ const chainId = Number(connectInfo.chainId);
281
+ const accounts = yield this.getAccounts();
282
+ config.emitter.emit("connect", { accounts, chainId });
283
+ });
284
+ },
285
+ onDisconnect(_error) {
286
+ return __async(this, null, function* () {
287
+ this.setRequestedChainsIds([]);
288
+ config.emitter.emit("disconnect");
289
+ const provider = yield this.getProvider();
290
+ if (accountsChanged) {
291
+ provider.removeListener("accountsChanged", accountsChanged);
292
+ accountsChanged = void 0;
293
+ }
294
+ if (chainChanged) {
295
+ provider.removeListener("chainChanged", chainChanged);
296
+ chainChanged = void 0;
297
+ }
298
+ if (disconnect) {
299
+ provider.removeListener("disconnect", disconnect);
300
+ disconnect = void 0;
301
+ }
302
+ if (sessionDelete) {
303
+ provider.removeListener("session_delete", sessionDelete);
304
+ sessionDelete = void 0;
305
+ }
306
+ if (!connect) {
307
+ connect = this.onConnect.bind(this);
308
+ provider.on("connect", connect);
309
+ }
310
+ });
311
+ },
312
+ onDisplayUri(uri) {
313
+ config.emitter.emit("message", { type: "display_uri", data: uri });
314
+ },
315
+ onSessionDelete() {
316
+ this.onDisconnect();
317
+ },
318
+ getNamespaceChainsIds() {
319
+ var _a3, _b, _c;
320
+ if (!provider_) return [];
321
+ const chainIds = (_c = (_b = (_a3 = provider_.session) == null ? void 0 : _a3.namespaces[NAMESPACE]) == null ? void 0 : _b.accounts) == null ? void 0 : _c.map(
322
+ (account) => Number.parseInt(account.split(":")[1] || "")
323
+ );
324
+ return chainIds != null ? chainIds : [];
325
+ },
326
+ getRequestedChainsIds() {
327
+ return __async(this, null, function* () {
328
+ var _a3, _b;
329
+ return (_b = yield (_a3 = config.storage) == null ? void 0 : _a3.getItem(this.requestedChainsStorageKey)) != null ? _b : [];
330
+ });
331
+ },
332
+ /**
333
+ * Checks if the target chains match the chains that were
334
+ * initially requested by the connector for the WalletConnect session.
335
+ * If there is a mismatch, this means that the chains on the connector
336
+ * are considered stale, and need to be revalidated at a later point (via
337
+ * connection).
338
+ *
339
+ * There may be a scenario where a dapp adds a chain to the
340
+ * connector later on, however, this chain will not have been approved or rejected
341
+ * by the wallet. In this case, the chain is considered stale.
342
+ */
343
+ isChainsStale() {
344
+ return __async(this, null, function* () {
345
+ if (!isNewChainsStale) return false;
346
+ const connectorChains = config.chains.map((x) => x.id);
347
+ const namespaceChains = this.getNamespaceChainsIds();
348
+ if (namespaceChains.length && !namespaceChains.some((id) => connectorChains.includes(id))) return false;
349
+ const requestedChains = yield this.getRequestedChainsIds();
350
+ return !connectorChains.every((id) => requestedChains.includes(id));
351
+ });
352
+ },
353
+ setRequestedChainsIds(chains) {
354
+ return __async(this, null, function* () {
355
+ var _a3;
356
+ yield (_a3 = config.storage) == null ? void 0 : _a3.setItem(this.requestedChainsStorageKey, chains);
357
+ });
358
+ },
359
+ get requestedChainsStorageKey() {
360
+ return `${this.id}.requestedChains`;
361
+ }
362
+ }));
363
+ }
364
+ export {
365
+ walletConnect
366
+ };
@@ -19,11 +19,12 @@ import {
19
19
  useBalance
20
20
  } from "wagmi";
21
21
  import { isEIP6963Connector } from "../utils/isEIP6963Connector.js";
22
- import { getWalletConnectUri } from "../utils/getWalletConnectUri.js";
22
+ import { emitWalletConnectUri } from "../utils/getWalletConnectUri.js";
23
23
  import { normalize } from "viem/ens";
24
24
  import { useExternalWalletStore } from "../stores/useStore.js";
25
25
  import {
26
- defaultEvmExternalWallet
26
+ defaultEvmExternalWallet,
27
+ openMobileUrl
27
28
  } from "@getpara/react-common";
28
29
  import { isMobile } from "@getpara/web-sdk";
29
30
  import { etherUnits, formatUnits } from "viem";
@@ -170,11 +171,21 @@ function EvmExternalWalletProvider({
170
171
  };
171
172
  };
172
173
  const signMessage = (_0) => __async(this, [_0], function* ({ message, externalWallet }) {
173
- var _a, _b, _c, _d, _e, _f, _g, _h;
174
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
174
175
  let signOpts = {};
176
+ const connector = findConnector(
177
+ externalWallet ? externalWallet.providerId : getConnectorInfo(connectedConnector).providerId
178
+ );
179
+ const signUri = isMobile() && connector.type === "walletConnect" ? (_a = connector.paraDetails) == null ? void 0 : _a.deeplinkUri : void 0;
180
+ const openApp = () => {
181
+ if (signUri) {
182
+ openMobileUrl(signUri);
183
+ }
184
+ };
185
+ openApp();
175
186
  if (externalWallet) {
176
187
  signOpts = findConnectorAndAccount(externalWallet);
177
- yield switchAccount((_a = externalWallet.providerId) != null ? _a : "");
188
+ yield switchAccount((_b = externalWallet.providerId) != null ? _b : "");
178
189
  }
179
190
  const address = signOpts.account ? typeof signOpts.account === "string" ? signOpts.account : signOpts.account.getAddress() : wagmiAddress;
180
191
  try {
@@ -191,7 +202,7 @@ function EvmExternalWalletProvider({
191
202
  console.error("Error signing message:", e.message, e.details);
192
203
  if (e.message.includes("Chain not configured") || e.details.includes("Chain not configured")) {
193
204
  setVerificationStage("switchingChain");
194
- const currentChainParams = getChainParams((_c = (_b = chains[0]) == null ? void 0 : _b.id) != null ? _c : chainId);
205
+ const currentChainParams = getChainParams((_d = (_c = chains[0]) == null ? void 0 : _c.id) != null ? _d : chainId);
195
206
  if (!currentChainParams) {
196
207
  return {
197
208
  error: `Chain ${chainId} not found in configuration`
@@ -200,14 +211,14 @@ function EvmExternalWalletProvider({
200
211
  try {
201
212
  yield switchChainAsync({
202
213
  addEthereumChainParameter: currentChainParams,
203
- chainId: (_e = (_d = chains[0]) == null ? void 0 : _d.id) != null ? _e : chainId
214
+ chainId: (_f = (_e = chains[0]) == null ? void 0 : _e.id) != null ? _f : chainId
204
215
  });
205
216
  setVerificationStage("verifying");
206
217
  return yield signMessage({ message, externalWallet });
207
218
  } catch (error) {
208
219
  console.error("Error adding chain:", error);
209
220
  return {
210
- error: `Error adding chain. You may need to add ${currentChainParams == null ? void 0 : currentChainParams.chainName} support to ${(_h = (_g = (_f = connectedConnector == null ? void 0 : connectedConnector.paraDetails) == null ? void 0 : _f.name) != null ? _g : connectedConnector == null ? void 0 : connectedConnector.name) != null ? _h : "the wallet"} manually.`
221
+ error: `Error adding chain. You may need to add ${currentChainParams == null ? void 0 : currentChainParams.chainName} support to ${(_i = (_h = (_g = connectedConnector == null ? void 0 : connectedConnector.paraDetails) == null ? void 0 : _g.name) != null ? _h : connectedConnector == null ? void 0 : connectedConnector.name) != null ? _i : "the wallet"} manually.`
211
222
  };
212
223
  }
213
224
  }
@@ -254,6 +265,7 @@ function EvmExternalWalletProvider({
254
265
  return { error };
255
266
  });
256
267
  const login = (_0) => __async(this, [_0], function* ({ address, withFullParaAuth = false, providerId, provider }) {
268
+ var _a, _b, _c;
257
269
  try {
258
270
  refetchEnsName();
259
271
  refetchEnsAvatar();
@@ -269,7 +281,9 @@ function EvmExternalWalletProvider({
269
281
  ensAvatar,
270
282
  isConnectionOnly: connectionOnly,
271
283
  withVerification: includeWalletVerification
272
- }
284
+ },
285
+ uri: window == null ? void 0 : window.location.origin,
286
+ chainId: (_c = (_b = (_a = chains[0]) == null ? void 0 : _a.id) != null ? _b : chainId) == null ? void 0 : _c.toString()
273
287
  });
274
288
  } catch (err) {
275
289
  yield disconnectAsync();
@@ -300,17 +314,20 @@ function EvmExternalWalletProvider({
300
314
  updateExternalWalletState({ isConnecting: false });
301
315
  });
302
316
  const connectBase = (connector) => __async(this, null, function* () {
303
- var _a, _b, _c, _d;
317
+ var _a, _b, _c, _d, _e, _f;
318
+ if (connector.type === "walletConnect" || ((_a = connector.paraDetails) == null ? void 0 : _a.internalId) === "WALLETCONNECT" || ((_b = connector.paraDetails) == null ? void 0 : _b.showQrModal)) {
319
+ yield emitWalletConnectUri(connector, connector.getUri);
320
+ }
304
321
  const walletChainId = yield connector.getChainId();
305
322
  const data = yield connectAsync({
306
323
  // If the wallet is already on a supported chain, use that to avoid a chain switch prompt.
307
- chainId: (_c = (_a = chains.find(({ id }) => id === walletChainId)) == null ? void 0 : _a.id) != null ? _c : (
324
+ chainId: (_e = (_c = chains.find(({ id }) => id === walletChainId)) == null ? void 0 : _c.id) != null ? _e : (
308
325
  // Fall back to the first chain provided.
309
- (_b = chains[0]) == null ? void 0 : _b.id
326
+ (_d = chains[0]) == null ? void 0 : _d.id
310
327
  ),
311
328
  connector
312
329
  });
313
- return (_d = data.accounts) == null ? void 0 : _d[0];
330
+ return (_f = data.accounts) == null ? void 0 : _f[0];
314
331
  });
315
332
  const connect = (connector) => __async(this, null, function* () {
316
333
  updateExternalWalletState({ isConnecting: true });
@@ -358,12 +375,14 @@ function EvmExternalWalletProvider({
358
375
  return yield connect(_connector);
359
376
  });
360
377
  const findConnector = (providerId) => {
361
- return connectorsRef.current.find(
378
+ var _a;
379
+ const connector = connectorsRef.current.find(
362
380
  (w) => {
363
- var _a, _b, _c;
364
- return [(_a = w == null ? void 0 : w.paraDetails) == null ? void 0 : _a.name, (_b = w == null ? void 0 : w.paraDetails) == null ? void 0 : _b.id, (_c = w == null ? void 0 : w.paraDetails) == null ? void 0 : _c.internalId].includes(providerId);
381
+ var _a2, _b, _c;
382
+ return [(_a2 = w == null ? void 0 : w.paraDetails) == null ? void 0 : _a2.name, (_b = w == null ? void 0 : w.paraDetails) == null ? void 0 : _b.id, (_c = w == null ? void 0 : w.paraDetails) == null ? void 0 : _c.internalId].includes(providerId);
365
383
  }
366
384
  );
385
+ return connector ? __spreadProps(__spreadValues({}, connector), { getUri: (_a = connector.paraDetails) == null ? void 0 : _a.getUri }) : void 0;
367
386
  };
368
387
  const requestInfo = (providerId) => __async(this, null, function* () {
369
388
  var _a, _b, _c, _d;
@@ -439,12 +458,11 @@ function EvmExternalWalletProvider({
439
458
  return c;
440
459
  }).filter((c) => !!c);
441
460
  const wallets = dedupedConnectors.map((c) => {
442
- var _a, _b, _c, _d, _e, _f, _g;
461
+ var _a, _b, _c, _d, _e;
443
462
  if (((_a = c.paraDetails) == null ? void 0 : _a.internalId) === "SAFE" && (typeof window === "undefined" || window.parent === window)) {
444
463
  return void 0;
445
464
  }
446
465
  const connector = __spreadValues(__spreadValues({}, c), c.paraDetails);
447
- const supportsWalletConnect = connector.type === "walletConnect" || ((_b = connector.paraDetails) == null ? void 0 : _b.internalId) === "WALLETCONNECT" || ((_c = connector.paraDetails) == null ? void 0 : _c.showQrModal);
448
466
  const isInjected = !c.paraDetails && eip6963Names.includes(c.name);
449
467
  if (isInjected && connectors.some((c2) => {
450
468
  var _a2;
@@ -452,17 +470,17 @@ function EvmExternalWalletProvider({
452
470
  })) {
453
471
  return void 0;
454
472
  }
455
- return __spreadValues(__spreadProps(__spreadValues({}, connector), {
473
+ return __spreadProps(__spreadValues({}, connector), {
456
474
  // Using name here since that's the only common id across the networks
457
475
  id: connector.name,
458
- internalId: (_d = connector.internalId) != null ? _d : connector.name,
459
- isExtension: (_e = connector.isExtension) != null ? _e : isInjected,
460
- installed: (_f = connector.installed) != null ? _f : isInjected,
461
- iconUrl: (_g = connector.iconUrl) != null ? _g : connector.icon,
476
+ internalId: (_b = connector.internalId) != null ? _b : connector.name,
477
+ isExtension: (_c = connector.isExtension) != null ? _c : isInjected,
478
+ installed: (_d = connector.installed) != null ? _d : isInjected,
479
+ iconUrl: (_e = connector.iconUrl) != null ? _e : connector.icon,
462
480
  connect: () => connect(connector),
463
481
  connectMobile: (manual) => connectMobile(connector, manual),
464
482
  type: "EVM"
465
- }), supportsWalletConnect && { getQrUri: () => getWalletConnectUri(connector, connector.getUri) });
483
+ });
466
484
  }).filter(Boolean);
467
485
  const getConnectorInfo = (connector) => {
468
486
  const paraDetails = connector.paraDetails;
@@ -1,13 +1,14 @@
1
1
  import { Connector, CreateConnectorFn } from 'wagmi';
2
- import { WalletConnectParameters } from 'wagmi/connectors';
3
2
  import { CoinbaseWalletOptions } from '../wallets/connectors/coinbase/coinbase.js';
4
3
  import { WalletConnectWalletOptions } from '../wallets/connectors/walletConnect/walletConnect.js';
5
4
  import { type WalletMetadata } from '@getpara/react-common';
6
5
  import ParaWeb from '@getpara/web-sdk';
6
+ import { WalletConnectParameters } from '../connectors/walletConnect.js';
7
7
  export type Wallet = {
8
8
  createConnector?: (walletDetails: WalletDetailsParams) => CreateConnectorFn;
9
9
  createMobileConnector?: (walletDetails: WalletDetailsParams) => CreateConnectorFn;
10
10
  getUri?: (uri: string) => string;
11
+ deeplinkUri?: string;
11
12
  } & WalletMetadata;
12
13
  export interface DefaultWalletOptions {
13
14
  para?: ParaWeb;
@@ -4,7 +4,7 @@ import {
4
4
  __spreadValues
5
5
  } from "../chunk-MMUBH76A.js";
6
6
  import { createConnector } from "wagmi";
7
- import { walletConnect } from "wagmi/connectors";
7
+ import { walletConnect } from "../connectors/walletConnect.js";
8
8
  const walletConnectInstances = /* @__PURE__ */ new Map();
9
9
  const getOrCreateWalletConnectInstance = ({
10
10
  projectId,
@@ -1,2 +1,2 @@
1
1
  import { Connector } from 'wagmi';
2
- export declare const getWalletConnectUri: (connector: Connector, uriConverter?: (uri: string) => string) => Promise<string>;
2
+ export declare const emitWalletConnectUri: (connector: Connector, uriConverter?: (uri: string) => string) => Promise<void>;
@@ -2,24 +2,27 @@
2
2
  import {
3
3
  __async
4
4
  } from "../chunk-MMUBH76A.js";
5
- const getWalletConnectUri = (connector, uriConverter) => __async(void 0, null, function* () {
5
+ const emitWalletConnectUri = (connector, uriConverter) => __async(void 0, null, function* () {
6
6
  var _a, _b;
7
+ if (typeof window === "undefined") {
8
+ return;
9
+ }
7
10
  const provider = yield (_b = (_a = connector.getProvider) == null ? void 0 : _a.call(connector)) != null ? _b : void 0;
8
11
  if (connector.type === "coinbaseWallet" && (provider == null ? void 0 : provider.qrUrl)) {
9
- return provider.qrUrl;
12
+ window.dispatchEvent(new CustomEvent("PARA_WALLETCONNECT_URI_READY", { detail: provider.qrUrl }));
10
13
  }
11
14
  if (!provider || typeof provider.once !== "function" && typeof provider.on !== "function") {
12
15
  throw new Error("display_uri event not supported for this connector");
13
16
  }
14
17
  const listen = typeof provider.once === "function" ? provider.once.bind(provider) : provider.on.bind(provider);
15
- return new Promise((resolve, reject) => {
16
- const cancel = setTimeout(() => reject(new Error("display_uri event not emitted")), 1e4);
17
- listen("display_uri", (uri) => {
18
- clearTimeout(cancel);
19
- resolve(uriConverter ? uriConverter(uri) : uri);
20
- });
18
+ const cancel = setTimeout(() => console.error("display_uri event not emitted"), 1e4);
19
+ listen("display_uri", (uri) => {
20
+ clearTimeout(cancel);
21
+ window.dispatchEvent(
22
+ new CustomEvent("PARA_WALLETCONNECT_URI_READY", { detail: uriConverter ? uriConverter(uri) : uri })
23
+ );
21
24
  });
22
25
  });
23
26
  export {
24
- getWalletConnectUri
27
+ emitWalletConnectUri
25
28
  };
@@ -55,11 +55,13 @@ const metaMaskWallet = ({ projectId, walletConnectParameters }) => {
55
55
  if (providerMapTarget) {
56
56
  metaMaskTarget = providerMapTarget;
57
57
  }
58
+ const deeplinkUri = "metamask://";
59
+ const baseUri = isAndroid() ? `${deeplinkUri}wc` : isIOS() ? !isTelegram() ? (
60
+ // currently broken in MetaMask v6.5.0 https://github.com/MetaMask/metamask-mobile/issues/6457
61
+ `${deeplinkUri}wc`
62
+ ) : "https://metamask.app.link/wc" : "https://metamask.app.link/wc";
58
63
  const getUri = (uri) => {
59
- return isAndroid() ? `metamask://wc?uri=${encodeURIComponent(uri)}` : isIOS() ? !isTelegram() ? (
60
- // currently broken in MetaMask v6.5.0 https://github.com/MetaMask/metamask-mobile/issues/6457
61
- `metamask://wc?uri=${encodeURIComponent(uri)}`
62
- ) : `https://metamask.app.link/wc?uri=${encodeURIComponent(uri)}` : `https://metamask.app.link/wc?uri=${encodeURIComponent(uri)}`;
64
+ return `${baseUri}?uri=${encodeURIComponent(uri)}`;
63
65
  };
64
66
  return {
65
67
  id: "metaMask",
@@ -72,6 +74,7 @@ const metaMaskWallet = ({ projectId, walletConnectParameters }) => {
72
74
  isMobile: true,
73
75
  downloadUrl: "https://metamask.io/download/",
74
76
  getUri,
77
+ deeplinkUri,
75
78
  createConnector: isMetaMaskInjected ? getInjectedConnector({
76
79
  target: metaMaskTarget
77
80
  }) : getWalletConnectConnector({
@@ -6,8 +6,13 @@ import { getWalletConnectConnector } from "../../../utils/getWalletConnectConnec
6
6
  import { icon } from "./rainbowIcon.js";
7
7
  const rainbowWallet = ({ projectId, walletConnectParameters }) => {
8
8
  const isRainbowInjected = hasInjectedProvider({ flag: "isRainbow" });
9
+ const deeplinkUri = "rainbow://";
10
+ const baseUri = isAndroid() ? `${deeplinkUri}wc` : isIOS() ? !isTelegram() ? (
11
+ // currently broken in MetaMask v6.5.0 https://github.com/MetaMask/metamask-mobile/issues/6457
12
+ `${deeplinkUri}wc`
13
+ ) : "https://rnbwapp.com/wc" : "https://rnbwapp.com/wc";
9
14
  const getUri = (uri) => {
10
- return isAndroid() ? `rainbow://wc?uri=${encodeURIComponent(uri)}` : isIOS() ? !isTelegram() ? `rainbow://wc?uri=${encodeURIComponent(uri)}` : `https://rnbwapp.com/wc?uri=${encodeURIComponent(uri)}` : `https://rnbwapp.com/wc?uri=${encodeURIComponent(uri)}`;
15
+ return `${baseUri}?uri=${encodeURIComponent(uri)}`;
11
16
  };
12
17
  return {
13
18
  id: "rainbow",
@@ -20,6 +25,7 @@ const rainbowWallet = ({ projectId, walletConnectParameters }) => {
20
25
  isMobile: true,
21
26
  downloadUrl: "https://rainbow.me/",
22
27
  getUri,
28
+ deeplinkUri,
23
29
  createConnector: isRainbowInjected ? getInjectedConnector({ flag: "isRainbow" }) : getWalletConnectConnector({
24
30
  projectId,
25
31
  walletConnectParameters
@@ -9,8 +9,10 @@ const zerionWallet = ({ projectId, walletConnectParameters }) => {
9
9
  namespace: "zerionWallet",
10
10
  flag: "isZerion"
11
11
  });
12
+ const deeplinkUri = "zerion://";
13
+ const baseUri = isTelegram() && isIOS() ? "https://app.zerion.io/wc" : `${deeplinkUri}wc`;
12
14
  const getUri = (uri) => {
13
- return isTelegram() && isIOS() ? `https://app.zerion.io/wc?uri=${encodeURIComponent(uri)}` : `zerion://wc?uri=${encodeURIComponent(uri)}`;
15
+ return `${baseUri}?uri=${encodeURIComponent(uri)}`;
14
16
  };
15
17
  return {
16
18
  id: "zerion",
@@ -22,6 +24,7 @@ const zerionWallet = ({ projectId, walletConnectParameters }) => {
22
24
  isExtension: true,
23
25
  isMobile: true,
24
26
  getUri,
27
+ deeplinkUri,
25
28
  downloadUrl: "https://zerion.io/download",
26
29
  createConnector: isZerionInjected ? getInjectedConnector({
27
30
  namespace: "zerionWallet",
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "@getpara/evm-wallet-connectors",
3
- "version": "2.0.0-alpha.67",
3
+ "version": "2.0.0-alpha.69",
4
4
  "dependencies": {
5
5
  "@coinbase/wallet-sdk": "4.3.0",
6
- "@getpara/wagmi-v2-connector": "2.0.0-alpha.67",
7
- "@getpara/web-sdk": "2.0.0-alpha.67",
6
+ "@getpara/wagmi-v2-connector": "2.0.0-alpha.69",
7
+ "@getpara/web-sdk": "2.0.0-alpha.69",
8
+ "@walletconnect/ethereum-provider": "^2.22.4",
8
9
  "zustand": "^4.5.2",
9
10
  "zustand-sync-tabs": "^0.2.2"
10
11
  },
11
12
  "devDependencies": {
12
- "@getpara/react-common": "2.0.0-alpha.67",
13
+ "@getpara/react-common": "2.0.0-alpha.69",
13
14
  "@tanstack/react-query": "^5.74.0",
14
15
  "@types/react": "^18.0.31",
15
16
  "@types/react-dom": "^18.2.7",
@@ -25,7 +26,7 @@
25
26
  "dist",
26
27
  "package.json"
27
28
  ],
28
- "gitHead": "0266cc49e978575fed0b12c9bb0c832651e140eb",
29
+ "gitHead": "956310e0ff58cc8e2736625d221245ab68304855",
29
30
  "main": "dist/index.js",
30
31
  "peerDependencies": {
31
32
  "@farcaster/miniapp-wagmi-connector": "^1.0.0",