@injectivelabs/wallet-evm 1.20.3 → 1.20.5

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/index.js CHANGED
@@ -1,227 +1,261 @@
1
1
  import { capitalize } from "@injectivelabs/utils";
2
2
  import { BitGetException, ErrorType, KeplrEvmException, MetamaskException, OkxWalletException, RabbyWalletException, RainbowWalletException, TransactionException, TrustWalletException, UnspecifiedErrorCode, WalletException } from "@injectivelabs/exceptions";
3
- import { BaseConcreteStrategy, Wallet, WalletAction, WalletDeviceType, WalletEventListener, getEvmChainConfig, getViemPublicClientFromEip1193Provider, isEvmBrowserWallet } from "@injectivelabs/wallet-base";
3
+ import { BaseConcreteStrategy, EvmWalletProviderErrorCode, Wallet, WalletAction, WalletDeviceType, WalletEventListener, getEvmChainConfig, getViemPublicClientFromEip1193Provider, isEvmBrowserWallet } from "@injectivelabs/wallet-base";
4
4
  import { TxGrpcApi } from "@injectivelabs/sdk-ts/core/tx";
5
5
  import { isServerSide, stringToUint8Array, toUtf8, uint8ArrayToHex } from "@injectivelabs/sdk-ts/utils";
6
6
 
7
- //#region src/strategy/utils/rabby.ts
8
- const getWindow$7 = () => typeof window === "undefined" ? {} : window;
9
- async function getRabbyProvider({ timeout } = { timeout: 3e3 }) {
10
- const provider = getRabbyFromWindow();
11
- if (provider) return provider;
12
- return listenForRabbyInitialized({ timeout });
13
- }
14
- async function listenForRabbyInitialized({ timeout } = { timeout: 3e3 }) {
7
+ //#region src/strategy/utils/providerResolver.ts
8
+ const EIP6963_REQUEST_TIMEOUT = 250;
9
+ const eip6963Providers = {};
10
+ const getWindow = () => typeof window === "undefined" ? {} : window;
11
+ const normalize = (value) => (value === null || value === void 0 ? void 0 : value.toLowerCase().trim()) || "";
12
+ const walletProviderMetadata = {
13
+ [Wallet.Metamask]: {
14
+ names: ["metamask"],
15
+ rdns: ["io.metamask", "io.metamask.flask"]
16
+ },
17
+ [Wallet.Rabby]: {
18
+ names: ["rabby", "rabby wallet"],
19
+ rdns: ["io.rabby"]
20
+ },
21
+ [Wallet.Rainbow]: {
22
+ names: ["rainbow", "rainbow wallet"],
23
+ rdns: ["me.rainbow"]
24
+ },
25
+ [Wallet.Phantom]: {
26
+ names: ["phantom", "phantom wallet"],
27
+ rdns: ["app.phantom"]
28
+ },
29
+ [Wallet.OkxWallet]: {
30
+ names: [
31
+ "okx",
32
+ "okx wallet",
33
+ "okxwallet"
34
+ ],
35
+ rdns: ["com.okex.wallet"]
36
+ },
37
+ [Wallet.BitGet]: {
38
+ names: [
39
+ "bitget",
40
+ "bitget wallet",
41
+ "bitkeep"
42
+ ],
43
+ rdns: ["com.bitget.web3", "com.bitget.wallet"]
44
+ },
45
+ [Wallet.TrustWallet]: {
46
+ names: [
47
+ "trust",
48
+ "trust wallet",
49
+ "trustwallet"
50
+ ],
51
+ rdns: ["com.trustwallet.app", "com.trustwallet"]
52
+ },
53
+ [Wallet.KeplrEvm]: {
54
+ names: [
55
+ "keplr",
56
+ "keplr wallet",
57
+ "keplr-evm"
58
+ ],
59
+ rdns: [
60
+ "app.keplr",
61
+ "io.keplr",
62
+ "io.keplr.wallet"
63
+ ]
64
+ }
65
+ };
66
+ const legacyProviderInitializedEvents = {
67
+ [Wallet.Metamask]: "ethereum#initialized",
68
+ [Wallet.Rabby]: "rabby#initialized",
69
+ [Wallet.Rainbow]: "rainbow#initialized",
70
+ [Wallet.Phantom]: "phantom#initialized",
71
+ [Wallet.OkxWallet]: "okxwallet#initialized",
72
+ [Wallet.BitGet]: "bitkeep#initialized",
73
+ [Wallet.TrustWallet]: "trustwallet#initialized",
74
+ [Wallet.KeplrEvm]: "keplr#initialized"
75
+ };
76
+ const competingMetaMaskFlags = [
77
+ "isRabby",
78
+ "isRainbow",
79
+ "isPhantom",
80
+ "isOkxWallet",
81
+ "isTrustWallet",
82
+ "isTrust",
83
+ "isKeplr"
84
+ ];
85
+ const isSupportedEip6963Wallet = (wallet) => wallet in walletProviderMetadata;
86
+ const providerHasCompetingMetaMaskFlag = (provider) => competingMetaMaskFlags.some((flag) => Boolean(provider[flag]));
87
+ const providerMatchesWallet = (provider, wallet) => {
88
+ if (!provider) return false;
89
+ const legacyProvider = provider;
90
+ if (wallet === Wallet.Metamask) return Boolean(provider.isMetaMask) && !providerHasCompetingMetaMaskFlag(provider);
91
+ if (wallet === Wallet.Rabby) return Boolean(provider.isRabby);
92
+ if (wallet === Wallet.Rainbow) return Boolean(provider.isRainbow);
93
+ if (wallet === Wallet.Phantom) return Boolean(provider.isPhantom);
94
+ if (wallet === Wallet.OkxWallet) return Boolean(provider.isOkxWallet);
95
+ if (wallet === Wallet.BitGet) return Boolean(legacyProvider.isBitKeep || legacyProvider.isBitGet);
96
+ if (wallet === Wallet.TrustWallet) return Boolean(provider.isTrustWallet || provider.isTrust);
97
+ if (wallet === Wallet.KeplrEvm) return Boolean(provider.isKeplr);
98
+ return false;
99
+ };
100
+ const getWalletFromEip6963ProviderDetail = (detail) => {
101
+ var _detail$info, _detail$info2, _entries$find;
102
+ const rdns = normalize((_detail$info = detail.info) === null || _detail$info === void 0 ? void 0 : _detail$info.rdns);
103
+ const name = normalize((_detail$info2 = detail.info) === null || _detail$info2 === void 0 ? void 0 : _detail$info2.name);
104
+ const entries = Object.entries(walletProviderMetadata);
105
+ const rdnsMatch = entries.find(([, metadata]) => metadata.rdns.some((value) => normalize(value) === rdns));
106
+ if (rdnsMatch) return rdnsMatch[0];
107
+ return (_entries$find = entries.find(([, metadata]) => metadata.names.some((value) => normalize(value) === name))) === null || _entries$find === void 0 ? void 0 : _entries$find[0];
108
+ };
109
+ const registerEip6963Provider = (detail, providerCache) => {
110
+ if (!(detail === null || detail === void 0 ? void 0 : detail.provider)) return;
111
+ const wallet = getWalletFromEip6963ProviderDetail(detail);
112
+ if (!wallet) return;
113
+ eip6963Providers[wallet] = detail.provider;
114
+ if (providerCache) providerCache[wallet] = detail.provider;
115
+ return wallet;
116
+ };
117
+ const listenForEip6963Providers = (providerCache) => {
118
+ if (typeof window === "undefined") return;
119
+ const handleAnnouncement = (announcement) => {
120
+ registerEip6963Provider(announcement.detail, providerCache);
121
+ };
122
+ window.addEventListener("eip6963:announceProvider", handleAnnouncement);
123
+ return () => window.removeEventListener("eip6963:announceProvider", handleAnnouncement);
124
+ };
125
+ const requestEip6963Providers = () => {
126
+ if (typeof window === "undefined") return;
127
+ window.dispatchEvent(new Event("eip6963:requestProvider"));
128
+ };
129
+ const requestEip6963Provider = (wallet, providerCache, timeout = EIP6963_REQUEST_TIMEOUT) => {
130
+ if (typeof window === "undefined" || timeout <= 0) return Promise.resolve(void 0);
15
131
  return new Promise((resolve) => {
16
- const handleInitialization = () => {
17
- resolve(getRabbyFromWindow());
132
+ let timeoutId;
133
+ let resolved = false;
134
+ let handleAnnouncement = (_announcement) => {};
135
+ const cleanup = () => {
136
+ window.removeEventListener("eip6963:announceProvider", handleAnnouncement);
137
+ if (timeoutId) clearTimeout(timeoutId);
18
138
  };
19
- const $window = getWindow$7();
20
- $window.addEventListener("rabby#initialized", handleInitialization, { once: true });
21
- setTimeout(() => {
22
- $window.removeEventListener("rabby#initialized", handleInitialization);
23
- resolve(null);
24
- }, timeout);
25
- });
26
- }
27
- function getRabbyFromWindow() {
28
- const $window = getWindow$7();
29
- if (!(typeof window !== "undefined" && typeof $window.ethereum !== "undefined")) return;
30
- if ($window.ethereum.isRabby) return $window.ethereum;
31
- if ($window.providers) return $window.providers.find((p) => p.isRabby);
32
- }
33
-
34
- //#endregion
35
- //#region src/strategy/utils/Okx.ts
36
- const getWindow$6 = () => typeof window === "undefined" ? {} : window;
37
- async function getOkxWalletProvider({ timeout } = { timeout: 3e3 }) {
38
- const provider = getOkxWalletFromWindow();
39
- if (provider) return provider;
40
- return listenForOkxWalletInitialized({ timeout });
41
- }
42
- async function listenForOkxWalletInitialized({ timeout } = { timeout: 3e3 }) {
43
- return new Promise((resolve) => {
44
- const handleInitialization = () => {
45
- resolve(getOkxWalletFromWindow());
139
+ const resolveProvider = (provider) => {
140
+ if (resolved) return;
141
+ resolved = true;
142
+ cleanup();
143
+ resolve(provider);
46
144
  };
47
- const $window = getWindow$6();
48
- $window.addEventListener("okxwallet#initialized", handleInitialization, { once: true });
49
- setTimeout(() => {
50
- $window.removeEventListener("okxwallet#initialized", handleInitialization);
51
- resolve(null);
52
- }, timeout);
53
- });
54
- }
55
- function getOkxWalletFromWindow() {
56
- const $window = getWindow$6();
57
- if (!(typeof window !== "undefined" && (typeof $window.ethereum !== "undefined" || typeof $window.okxwallet !== "undefined"))) return;
58
- if ($window.okxwallet) return $window.okxwallet;
59
- if ($window.ethereum.isOkxWallet) return $window.ethereum;
60
- if ($window.providers) return $window.providers.find((p) => p.isOkxWallet);
61
- }
62
-
63
- //#endregion
64
- //#region src/strategy/utils/bitget.ts
65
- const getWindow$5 = () => typeof window === "undefined" ? {} : window;
66
- async function getBitGetProvider({ timeout } = { timeout: 3e3 }) {
67
- const provider = getBitGetFromWindow();
68
- if (provider) return provider;
69
- return listenForBitGetInitialized({ timeout });
70
- }
71
- async function listenForBitGetInitialized({ timeout } = { timeout: 3e3 }) {
72
- return new Promise((resolve) => {
73
- const handleInitialization = () => {
74
- resolve(getBitGetFromWindow());
145
+ handleAnnouncement = (announcement) => {
146
+ if (registerEip6963Provider(announcement.detail, providerCache) === wallet) resolveProvider((providerCache === null || providerCache === void 0 ? void 0 : providerCache[wallet]) || eip6963Providers[wallet]);
75
147
  };
76
- const $window = getWindow$5();
77
- $window.addEventListener("bitkeep#initialized", handleInitialization, { once: true });
78
- setTimeout(() => {
79
- $window.removeEventListener("bitkeep#initialized", handleInitialization);
80
- resolve(null);
81
- }, timeout);
82
- });
83
- }
84
- function getBitGetFromWindow() {
85
- const $window = getWindow$5();
86
- if (!(typeof window !== "undefined" && (typeof $window.ethereum !== "undefined" || typeof $window.bitkeep !== "undefined"))) return;
87
- if ($window.bitkeep && $window.bitkeep.ethereum) return $window.bitkeep.ethereum;
88
- }
89
-
90
- //#endregion
91
- //#region src/strategy/utils/phantom.ts
92
- const getWindow$4 = () => typeof window === "undefined" ? {} : window;
93
- async function getPhantomProvider({ timeout } = { timeout: 3e3 }) {
94
- const provider = getPhantomFromWindow();
95
- if (provider) return provider;
96
- return listenForPhantomInitialized({ timeout });
97
- }
98
- async function listenForPhantomInitialized({ timeout } = { timeout: 3e3 }) {
99
- return new Promise((resolve) => {
100
- const handleInitialization = () => {
101
- resolve(getPhantomFromWindow());
102
- };
103
- const $window = getWindow$4();
104
- $window.addEventListener("phantom#initialized", handleInitialization, { once: true });
105
- setTimeout(() => {
106
- $window.removeEventListener("phantom#initialized", handleInitialization);
107
- resolve(null);
148
+ window.addEventListener("eip6963:announceProvider", handleAnnouncement);
149
+ timeoutId = setTimeout(() => {
150
+ resolveProvider((providerCache === null || providerCache === void 0 ? void 0 : providerCache[wallet]) || eip6963Providers[wallet]);
108
151
  }, timeout);
152
+ requestEip6963Providers();
109
153
  });
110
- }
111
- function getPhantomFromWindow() {
112
- const $window = getWindow$4();
113
- if (!(typeof window !== "undefined" && (typeof $window.ethereum !== "undefined" || typeof $window.phantom !== "undefined"))) return;
114
- if ($window.phantom) return $window.phantom.ethereum;
115
- if ($window.ethereum.isPhantom) return $window.ethereum;
116
- if ($window.providers) return $window.providers.find((p) => p.isPhantom);
117
- }
118
-
119
- //#endregion
120
- //#region src/strategy/utils/keplrEvm.ts
121
- const getWindow$3 = () => typeof window === "undefined" ? {} : window;
122
- async function getKeplrEvmProvider({ timeout } = { timeout: 3e3 }) {
123
- const provider = getKeplrEvmFromWindow();
124
- if (provider) return provider;
125
- return listenForKeplrEvmInitialized({ timeout });
126
- }
127
- async function listenForKeplrEvmInitialized({ timeout } = { timeout: 3e3 }) {
128
- return new Promise((resolve) => {
129
- const handleInitialization = () => {
130
- resolve(getKeplrEvmFromWindow());
131
- };
132
- const $window = getWindow$3();
133
- $window.addEventListener("keplr#initialized", handleInitialization, { once: true });
134
- setTimeout(() => {
135
- $window.removeEventListener("keplr#initialized", handleInitialization);
136
- resolve(null);
137
- }, timeout);
154
+ };
155
+ const uniqueProviders = (providers) => {
156
+ const providerSet = /* @__PURE__ */ new Set();
157
+ providers.forEach((provider) => {
158
+ if (provider) providerSet.add(provider);
138
159
  });
139
- }
140
- function getKeplrEvmFromWindow() {
141
- var _keplr, _keplr2, _$window$ethereum;
142
- const $window = getWindow$3();
143
- if (!(typeof window !== "undefined" && (typeof $window.ethereum !== "undefined" || typeof ((_keplr = $window.keplr) === null || _keplr === void 0 ? void 0 : _keplr.ethereum) !== "undefined"))) return;
144
- if ((_keplr2 = $window.keplr) === null || _keplr2 === void 0 ? void 0 : _keplr2.ethereum) return $window.keplr.ethereum;
145
- if ((_$window$ethereum = $window.ethereum) === null || _$window$ethereum === void 0 ? void 0 : _$window$ethereum.isKeplr) return $window.ethereum;
146
- if ($window.providers) return $window.providers.find((p) => p.isKeplr);
147
- }
148
-
149
- //#endregion
150
- //#region src/strategy/utils/metamask.ts
151
- const getWindow$2 = () => typeof window === "undefined" ? {} : window;
152
- async function getMetamaskProvider({ timeout } = { timeout: 3e3 }) {
153
- const provider = getMetamaskFromWindow();
160
+ return [...providerSet];
161
+ };
162
+ const getWalletGlobalProvider = (wallet, $window) => {
163
+ if (wallet === Wallet.Rabby) return $window.rabby;
164
+ if (wallet === Wallet.Rainbow) return $window.rainbow;
165
+ if (wallet === Wallet.Phantom) {
166
+ var _$window$phantom;
167
+ return (_$window$phantom = $window.phantom) === null || _$window$phantom === void 0 ? void 0 : _$window$phantom.ethereum;
168
+ }
169
+ if (wallet === Wallet.OkxWallet) return $window.okxwallet;
170
+ if (wallet === Wallet.BitGet) {
171
+ var _$window$bitkeep;
172
+ return (_$window$bitkeep = $window.bitkeep) === null || _$window$bitkeep === void 0 ? void 0 : _$window$bitkeep.ethereum;
173
+ }
174
+ if (wallet === Wallet.TrustWallet) return $window.trustWallet;
175
+ if (wallet === Wallet.KeplrEvm) {
176
+ var _$window$keplr;
177
+ return (_$window$keplr = $window.keplr) === null || _$window$keplr === void 0 ? void 0 : _$window$keplr.ethereum;
178
+ }
179
+ };
180
+ const getLegacyEvmProvider = (wallet) => {
181
+ const $window = getWindow();
182
+ const ethereum = $window.ethereum;
183
+ const walletGlobalProvider = getWalletGlobalProvider(wallet, $window);
184
+ if (walletGlobalProvider) return walletGlobalProvider;
185
+ const providerFromArray = uniqueProviders([...(ethereum === null || ethereum === void 0 ? void 0 : ethereum.providers) || [], ...$window.providers || []]).find((provider) => providerMatchesWallet(provider, wallet));
186
+ if (providerFromArray) return providerFromArray;
187
+ if (providerMatchesWallet(ethereum, wallet)) return ethereum;
188
+ };
189
+ const resolveEvmProvider = async (wallet, options = {}) => {
190
+ if (!isSupportedEip6963Wallet(wallet)) return;
191
+ const { eip6963Providers: providerCache, requestEip6963 = true, timeout = EIP6963_REQUEST_TIMEOUT } = options;
192
+ const cachedProvider = (providerCache === null || providerCache === void 0 ? void 0 : providerCache[wallet]) || eip6963Providers[wallet];
193
+ if (cachedProvider) return cachedProvider;
194
+ if (requestEip6963) {
195
+ const announcedProvider = await requestEip6963Provider(wallet, providerCache, timeout);
196
+ if (announcedProvider) return announcedProvider;
197
+ }
198
+ return getLegacyEvmProvider(wallet);
199
+ };
200
+ const getEvmProviderWithFallback = async (wallet, options = {}) => {
201
+ const { eip6963Providers: providerCache, timeout = 3e3 } = options;
202
+ const provider = await resolveEvmProvider(wallet, { eip6963Providers: providerCache });
154
203
  if (provider) return provider;
155
- return listenForMetamaskInitialized({ timeout });
156
- }
157
- async function listenForMetamaskInitialized({ timeout } = { timeout: 3e3 }) {
204
+ const eventName = legacyProviderInitializedEvents[wallet];
205
+ if (typeof window === "undefined" || !eventName) return;
158
206
  return new Promise((resolve) => {
159
- const handleInitialization = () => {
160
- resolve(getMetamaskFromWindow());
207
+ let timeoutId;
208
+ let handleInitialization = async () => {};
209
+ const cleanup = () => {
210
+ window.removeEventListener(eventName, handleInitialization);
211
+ if (timeoutId) clearTimeout(timeoutId);
161
212
  };
162
- const $window = getWindow$2();
163
- $window.addEventListener("ethereum#initialized", handleInitialization, { once: true });
164
- setTimeout(() => {
165
- $window.removeEventListener("ethereum#initialized", handleInitialization);
166
- resolve(null);
167
- }, timeout);
168
- });
169
- }
170
- function getMetamaskFromWindow() {
171
- const $window = getWindow$2();
172
- if (!(typeof window !== "undefined" && typeof $window.ethereum !== "undefined")) return;
173
- if ($window.ethereum.isMetaMask) return $window.ethereum;
174
- if ($window.providers) return $window.providers.find((p) => p.isMetaMask);
175
- }
176
-
177
- //#endregion
178
- //#region src/strategy/utils/trustWallet.ts
179
- const getWindow$1 = () => typeof window === "undefined" ? {} : window;
180
- async function getTrustWalletProvider({ timeout } = { timeout: 3e3 }) {
181
- const provider = getTrustWalletFromWindow();
182
- if (provider) return provider;
183
- return listenForTrustWalletInitialized({ timeout });
184
- }
185
- async function listenForTrustWalletInitialized({ timeout } = { timeout: 3e3 }) {
186
- return new Promise((resolve) => {
187
- const handleInitialization = () => {
188
- resolve(getTrustWalletFromWindow());
213
+ handleInitialization = async () => {
214
+ cleanup();
215
+ resolve(await resolveEvmProvider(wallet, {
216
+ eip6963Providers: providerCache,
217
+ requestEip6963: false
218
+ }));
189
219
  };
190
- const $window = getWindow$1();
191
- $window.addEventListener("trustwallet#initialized", handleInitialization, { once: true });
192
- setTimeout(() => {
193
- $window.removeEventListener("trustwallet#initialized", handleInitialization);
194
- resolve(null);
220
+ window.addEventListener(eventName, handleInitialization, { once: true });
221
+ timeoutId = setTimeout(() => {
222
+ cleanup();
223
+ resolve(void 0);
195
224
  }, timeout);
196
225
  });
197
- }
198
- function getTrustWalletFromWindow() {
199
- const $window = getWindow$1();
200
- if (!(typeof window !== "undefined" && (typeof $window.ethereum !== "undefined" || typeof $window.trustWallet !== "undefined"))) return;
201
- if ($window.trustWallet) return $window.trustWallet;
202
- if ($window.ethereum.isTrustWallet || $window.ethereum.isTrust) return $window.ethereum;
203
- if ($window.providers) return $window.providers.find((p) => p.isTrustWallet);
204
- }
226
+ };
205
227
 
206
228
  //#endregion
207
229
  //#region src/utils/index.ts
230
+ const EVM_WALLET_INVALID_REQUEST_ERROR_CODE = -32600;
231
+ const CHAIN_NOT_SUPPORTED_MESSAGE_REGEX = /\b(chain(?:\s+id)?\s+not supported|unsupported\s+chain(?:\s+id)?)\b/;
208
232
  const getEvmProvider = async (wallet) => {
209
233
  if (!isEvmBrowserWallet(wallet)) throw new WalletException(/* @__PURE__ */ new Error(`Evm Wallet for ${capitalize(wallet)} is not supported.`));
210
234
  try {
211
- let provider;
212
- if (wallet === Wallet.Metamask) provider = await getMetamaskProvider();
213
- if (wallet === Wallet.Rabby) provider = await getRabbyProvider();
214
- if (wallet === Wallet.BitGet) provider = await getBitGetProvider();
215
- if (wallet === Wallet.Phantom) provider = await getPhantomProvider();
216
- if (wallet === Wallet.TrustWallet) provider = await getTrustWalletProvider();
217
- if (wallet === Wallet.OkxWallet) provider = await getOkxWalletProvider();
218
- if (wallet === Wallet.KeplrEvm) provider = await getKeplrEvmProvider();
235
+ const provider = await getEvmProviderWithFallback(wallet);
219
236
  if (!provider) throw new WalletException(/* @__PURE__ */ new Error(`Please install ${capitalize(wallet)} Extension`));
220
237
  return provider;
221
238
  } catch (_unused) {
222
239
  throw new WalletException(/* @__PURE__ */ new Error(`Please install ${capitalize(wallet)} Extension`));
223
240
  }
224
241
  };
242
+ const extractNormalizedErrorCode = (error) => {
243
+ var _normalizedError$data;
244
+ const normalizedError = error && typeof error === "object" ? error : void 0;
245
+ const code = normalizedError === null || normalizedError === void 0 ? void 0 : normalizedError.code;
246
+ const originalCode = normalizedError === null || normalizedError === void 0 || (_normalizedError$data = normalizedError.data) === null || _normalizedError$data === void 0 || (_normalizedError$data = _normalizedError$data.originalError) === null || _normalizedError$data === void 0 ? void 0 : _normalizedError$data.code;
247
+ const rawCode = (code != null ? Number(code) : void 0) === EvmWalletProviderErrorCode.InternalError || code === void 0 || code === null ? originalCode !== null && originalCode !== void 0 ? originalCode : code : code;
248
+ return rawCode != null ? Number(rawCode) : NaN;
249
+ };
250
+ const isUnrecognizedChainError = (error) => {
251
+ var _ref, _normalizedError$data2, _normalizedError$data3;
252
+ const errorCode = extractNormalizedErrorCode(error);
253
+ if (errorCode === EvmWalletProviderErrorCode.UnrecognizedChain) return true;
254
+ if (errorCode !== EVM_WALLET_INVALID_REQUEST_ERROR_CODE) return false;
255
+ const normalizedError = error && typeof error === "object" ? error : void 0;
256
+ const message = String((_ref = (_normalizedError$data2 = normalizedError === null || normalizedError === void 0 || (_normalizedError$data3 = normalizedError.data) === null || _normalizedError$data3 === void 0 || (_normalizedError$data3 = _normalizedError$data3.originalError) === null || _normalizedError$data3 === void 0 ? void 0 : _normalizedError$data3.message) !== null && _normalizedError$data2 !== void 0 ? _normalizedError$data2 : normalizedError === null || normalizedError === void 0 ? void 0 : normalizedError.message) !== null && _ref !== void 0 ? _ref : "").toLowerCase();
257
+ return CHAIN_NOT_SUPPORTED_MESSAGE_REGEX.test(message);
258
+ };
225
259
  const switchEthereumChainWithTimeout = async (provider, chainIdHex, timeoutMs = 3e4) => {
226
260
  let timeoutId;
227
261
  let handleChainChanged;
@@ -254,22 +288,19 @@ const switchEthereumChainWithTimeout = async (provider, chainIdHex, timeoutMs =
254
288
  });
255
289
  await Promise.race([switchRequest, chainChangedWaiter]);
256
290
  };
257
- const updateEvmNetwork = async (wallet, chainId) => {
291
+ const updateEvmNetwork = async (wallet, chainId, providerOverride) => {
258
292
  if (!isEvmBrowserWallet(wallet)) throw new WalletException(/* @__PURE__ */ new Error(`Evm Wallet for ${capitalize(wallet)} is not supported.`));
259
- const provider = await getEvmProvider(wallet);
293
+ const provider = providerOverride || await getEvmProvider(wallet);
260
294
  if (!provider) throw new WalletException(/* @__PURE__ */ new Error(`Please install ${capitalize(wallet)} Extension`));
261
295
  const chainIdToHex = `0x${chainId.toString(16)}`;
262
296
  const TIMEOUT_MS = 3e4;
263
297
  try {
264
298
  await switchEthereumChainWithTimeout(provider, chainIdToHex, TIMEOUT_MS);
265
299
  } catch (switchError) {
266
- var _switchError$code, _switchError$data, _chainConfig$rpcUrls, _chainConfig$blockExp;
267
- const rawCode = (_switchError$code = switchError === null || switchError === void 0 ? void 0 : switchError.code) !== null && _switchError$code !== void 0 ? _switchError$code : switchError === null || switchError === void 0 || (_switchError$data = switchError.data) === null || _switchError$data === void 0 || (_switchError$data = _switchError$data.originalError) === null || _switchError$data === void 0 ? void 0 : _switchError$data.code;
268
- const parsed = rawCode != null ? Number(rawCode) : NaN;
269
- const errorCode = !isNaN(parsed) ? parsed : void 0;
270
- if (errorCode === 4001) throw new WalletException(/* @__PURE__ */ new Error(`${capitalize(wallet)} chain switch was rejected`));
300
+ var _chainConfig$rpcUrls, _chainConfig$blockExp;
301
+ if (extractNormalizedErrorCode(switchError) === EvmWalletProviderErrorCode.UserRejectedRequest) throw new WalletException(/* @__PURE__ */ new Error(`${capitalize(wallet)} chain switch was rejected`));
271
302
  if (switchError.message === "Chain switch timed out") throw new WalletException(/* @__PURE__ */ new Error("Chain switch timed out"));
272
- if (errorCode !== 4902) throw new WalletException(/* @__PURE__ */ new Error(`Please update your ${capitalize(wallet)} network`));
303
+ if (!isUnrecognizedChainError(switchError)) throw new WalletException(/* @__PURE__ */ new Error(`Please update your ${capitalize(wallet)} network`));
273
304
  const chainConfig = getEvmChainConfig(chainId);
274
305
  const rpcUrl = (_chainConfig$rpcUrls = chainConfig.rpcUrls) === null || _chainConfig$rpcUrls === void 0 || (_chainConfig$rpcUrls = _chainConfig$rpcUrls.default) === null || _chainConfig$rpcUrls === void 0 || (_chainConfig$rpcUrls = _chainConfig$rpcUrls.http) === null || _chainConfig$rpcUrls === void 0 ? void 0 : _chainConfig$rpcUrls[0];
275
306
  const explorerUrl = ((_chainConfig$blockExp = chainConfig.blockExplorers) === null || _chainConfig$blockExp === void 0 || (_chainConfig$blockExp = _chainConfig$blockExp.default) === null || _chainConfig$blockExp === void 0 ? void 0 : _chainConfig$blockExp.url) || void 0;
@@ -284,55 +315,92 @@ const updateEvmNetwork = async (wallet, chainId) => {
284
315
  blockExplorerUrls: explorerUrl ? [explorerUrl] : []
285
316
  }]
286
317
  });
287
- } catch (_unused2) {
318
+ } catch (addError) {
319
+ if (extractNormalizedErrorCode(addError) === EvmWalletProviderErrorCode.UserRejectedRequest) throw new WalletException(/* @__PURE__ */ new Error(`${capitalize(wallet)} add chain was rejected`), {
320
+ code: EvmWalletProviderErrorCode.UserRejectedRequest,
321
+ type: ErrorType.WalletError,
322
+ contextModule: WalletAction.GetChainId
323
+ });
288
324
  throw new WalletException(/* @__PURE__ */ new Error(`Failed to add ${chainConfig.name} network to ${capitalize(wallet)}`));
289
325
  }
290
326
  let currentChainId;
291
327
  try {
292
328
  currentChainId = await provider.request({ method: "eth_chainId" });
293
- } catch (_unused3) {
329
+ } catch (_unused2) {
294
330
  throw new WalletException(/* @__PURE__ */ new Error(`Failed to get current chain ID from ${capitalize(wallet)} wallet`));
295
331
  }
296
332
  if (typeof currentChainId !== "string" || !currentChainId.startsWith("0x")) throw new WalletException(/* @__PURE__ */ new Error(`Invalid chain ID response from ${capitalize(wallet)}: ${String(currentChainId)}`));
297
333
  if (currentChainId.toLowerCase() !== chainIdToHex.toLowerCase()) try {
298
334
  await switchEthereumChainWithTimeout(provider, chainIdToHex, TIMEOUT_MS);
299
335
  } catch (postAddError) {
300
- var _postAddError$code, _postAddError$data;
301
- const rawCode$1 = (_postAddError$code = postAddError === null || postAddError === void 0 ? void 0 : postAddError.code) !== null && _postAddError$code !== void 0 ? _postAddError$code : postAddError === null || postAddError === void 0 || (_postAddError$data = postAddError.data) === null || _postAddError$data === void 0 || (_postAddError$data = _postAddError$data.originalError) === null || _postAddError$data === void 0 ? void 0 : _postAddError$data.code;
302
- const parsed$1 = rawCode$1 != null ? Number(rawCode$1) : NaN;
303
- if ((!isNaN(parsed$1) ? parsed$1 : void 0) === 4001) throw new WalletException(/* @__PURE__ */ new Error(`${capitalize(wallet)} chain switch after add was rejected`));
336
+ if (extractNormalizedErrorCode(postAddError) === EvmWalletProviderErrorCode.UserRejectedRequest) throw new WalletException(/* @__PURE__ */ new Error(`${capitalize(wallet)} chain switch after add was rejected`));
304
337
  throw new WalletException(/* @__PURE__ */ new Error(`Failed to switch to ${chainConfig.name} network after adding it: ${postAddError.message}`));
305
338
  }
306
339
  }
307
340
  };
308
341
 
342
+ //#endregion
343
+ //#region src/strategy/utils/rabby.ts
344
+ async function getRabbyProvider({ timeout } = { timeout: 3e3 }) {
345
+ const provider = await getEvmProviderWithFallback(Wallet.Rabby, { timeout });
346
+ if (!provider) throw new Error(`Please install the ${Wallet.Rabby} wallet extension.`);
347
+ return provider;
348
+ }
349
+
350
+ //#endregion
351
+ //#region src/strategy/utils/bitget.ts
352
+ async function getBitGetProvider({ timeout } = { timeout: 3e3 }) {
353
+ const provider = await getEvmProviderWithFallback(Wallet.BitGet, { timeout });
354
+ if (!provider) throw new Error(`Please install the ${Wallet.BitGet} wallet extension.`);
355
+ return provider;
356
+ }
357
+
358
+ //#endregion
359
+ //#region src/strategy/utils/Okx.ts
360
+ async function getOkxWalletProvider({ timeout } = { timeout: 3e3 }) {
361
+ const provider = await getEvmProviderWithFallback(Wallet.OkxWallet, { timeout });
362
+ if (!provider) throw new Error(`Please install the ${Wallet.OkxWallet} wallet extension.`);
363
+ return provider;
364
+ }
365
+
366
+ //#endregion
367
+ //#region src/strategy/utils/phantom.ts
368
+ async function getPhantomProvider({ timeout } = { timeout: 3e3 }) {
369
+ const provider = await getEvmProviderWithFallback(Wallet.Phantom, { timeout });
370
+ if (!provider) throw new Error(`Please install the ${Wallet.Phantom} wallet extension.`);
371
+ return provider;
372
+ }
373
+
309
374
  //#endregion
310
375
  //#region src/strategy/utils/rainbow.ts
311
- const getWindow = () => typeof window === "undefined" ? {} : window;
312
376
  async function getRainbowProvider({ timeout } = { timeout: 3e3 }) {
313
- const provider = getRainbowWalletFromWindow();
314
- if (provider) return provider;
315
- return listenForRainbowWalletInitialized({ timeout });
377
+ const provider = await getEvmProviderWithFallback(Wallet.Rainbow, { timeout });
378
+ if (!provider) throw new Error(`Please install the ${Wallet.Rainbow} wallet extension.`);
379
+ return provider;
316
380
  }
317
- async function listenForRainbowWalletInitialized({ timeout } = { timeout: 3e3 }) {
318
- return new Promise((resolve) => {
319
- const handleInitialization = () => {
320
- resolve(getRainbowWalletFromWindow());
321
- };
322
- const $window = getWindow();
323
- $window.addEventListener("rainbow#initialized", handleInitialization, { once: true });
324
- setTimeout(() => {
325
- $window.removeEventListener("rainbow#initialized", handleInitialization);
326
- resolve(null);
327
- }, timeout);
328
- });
381
+
382
+ //#endregion
383
+ //#region src/strategy/utils/metamask.ts
384
+ async function getMetamaskProvider({ timeout } = { timeout: 3e3 }) {
385
+ const provider = await getEvmProviderWithFallback(Wallet.Metamask, { timeout });
386
+ if (!provider) throw new Error(`Please install the ${Wallet.Metamask} wallet extension.`);
387
+ return provider;
329
388
  }
330
- function getRainbowWalletFromWindow() {
331
- const $window = getWindow();
332
- if (!(typeof window !== "undefined" && (typeof $window.ethereum !== "undefined" || typeof $window.rainbow !== "undefined"))) return;
333
- if ($window.rainbow) return $window.rainbow;
334
- if ($window.ethereum.isRainbow) return $window.ethereum;
335
- if ($window.providers) return $window.providers.find((p) => p.isRainbow);
389
+
390
+ //#endregion
391
+ //#region src/strategy/utils/keplrEvm.ts
392
+ async function getKeplrEvmProvider({ timeout } = { timeout: 3e3 }) {
393
+ const provider = await getEvmProviderWithFallback(Wallet.KeplrEvm, { timeout });
394
+ if (!provider) throw new Error(`Please install the ${Wallet.KeplrEvm} wallet extension.`);
395
+ return provider;
396
+ }
397
+
398
+ //#endregion
399
+ //#region src/strategy/utils/trustWallet.ts
400
+ async function getTrustWalletProvider({ timeout } = { timeout: 3e3 }) {
401
+ const provider = await getEvmProviderWithFallback(Wallet.TrustWallet, { timeout });
402
+ if (!provider) throw new Error(`Please install the ${Wallet.TrustWallet} wallet extension.`);
403
+ return provider;
336
404
  }
337
405
 
338
406
  //#endregion
@@ -386,19 +454,8 @@ var EvmWallet = class extends BaseConcreteStrategy {
386
454
  _defineProperty(this, "evmProviders", {});
387
455
  if (!isEvmBrowserWallet(args.wallet)) throw new WalletException(/* @__PURE__ */ new Error(`Evm Wallet for ${capitalize(args.wallet)} is not supported.`));
388
456
  if (!isServerSide()) {
389
- window.addEventListener("eip6963:announceProvider", (announcement) => {
390
- const event = announcement;
391
- const walletName = event.detail.info.name.toLowerCase();
392
- if (walletName === "keplr") this.evmProviders[Wallet.KeplrEvm] = event.detail.provider;
393
- if (walletName === Wallet.Metamask.toLowerCase()) this.evmProviders[Wallet.Metamask] = event.detail.provider;
394
- if (walletName === "rabby wallet") this.evmProviders[Wallet.Rabby] = event.detail.provider;
395
- if (walletName === Wallet.Rainbow.toLowerCase()) this.evmProviders[Wallet.Rainbow] = event.detail.provider;
396
- if (walletName === Wallet.Phantom.toLowerCase()) this.evmProviders[Wallet.Phantom] = event.detail.provider;
397
- if (walletName === Wallet.OkxWallet.toLowerCase()) this.evmProviders[Wallet.OkxWallet] = event.detail.provider;
398
- if (walletName === Wallet.BitGet.toLowerCase()) this.evmProviders[Wallet.BitGet] = event.detail.provider;
399
- if (walletName === Wallet.TrustWallet.toLowerCase()) this.evmProviders[Wallet.TrustWallet] = event.detail.provider;
400
- });
401
- window.dispatchEvent(new Event("eip6963:requestProvider"));
457
+ listenForEip6963Providers(this.evmProviders);
458
+ requestEip6963Providers();
402
459
  }
403
460
  this.wallet = args.wallet;
404
461
  }
@@ -580,11 +637,7 @@ var EvmWallet = class extends BaseConcreteStrategy {
580
637
  try {
581
638
  await switchEthereumChainWithTimeout(ethereum, chainIdHex, TIMEOUT_MS);
582
639
  } catch (error) {
583
- var _code, _data;
584
- const rawCode = (_code = error.code) !== null && _code !== void 0 ? _code : error === null || error === void 0 || (_data = error.data) === null || _data === void 0 || (_data = _data.originalError) === null || _data === void 0 ? void 0 : _data.code;
585
- const parsed = rawCode != null ? Number(rawCode) : NaN;
586
- const errorCode = !isNaN(parsed) ? parsed : void 0;
587
- if (errorCode === 4001) throw this.EvmWalletException(/* @__PURE__ */ new Error(`${capitalize(this.wallet || "wallet")} chain switch was rejected`), {
640
+ if (extractNormalizedErrorCode(error) === EvmWalletProviderErrorCode.UserRejectedRequest) throw this.EvmWalletException(/* @__PURE__ */ new Error(`${capitalize(this.wallet || "wallet")} chain switch was rejected`), {
588
641
  code: UnspecifiedErrorCode,
589
642
  type: ErrorType.WalletError,
590
643
  contextModule: WalletAction.GetChainId
@@ -594,7 +647,7 @@ var EvmWallet = class extends BaseConcreteStrategy {
594
647
  type: ErrorType.WalletError,
595
648
  contextModule: WalletAction.GetChainId
596
649
  });
597
- if (errorCode !== 4902) throw this.EvmWalletException(/* @__PURE__ */ new Error(`Something went wrong while switching ${capitalize(this.wallet || "wallet")} network`), {
650
+ if (!isUnrecognizedChainError(error)) throw this.EvmWalletException(/* @__PURE__ */ new Error(`Something went wrong while switching ${capitalize(this.wallet || "wallet")} network`), {
598
651
  code: UnspecifiedErrorCode,
599
652
  type: ErrorType.WalletError,
600
653
  contextModule: WalletAction.GetChainId
@@ -604,7 +657,12 @@ var EvmWallet = class extends BaseConcreteStrategy {
604
657
  method: "wallet_addEthereumChain",
605
658
  params: [params]
606
659
  });
607
- } catch (_unused2) {
660
+ } catch (addError) {
661
+ if (extractNormalizedErrorCode(addError) === EvmWalletProviderErrorCode.UserRejectedRequest) throw this.EvmWalletException(/* @__PURE__ */ new Error(`${capitalize(this.wallet || "wallet")} add chain was rejected`), {
662
+ code: EvmWalletProviderErrorCode.UserRejectedRequest,
663
+ type: ErrorType.WalletError,
664
+ contextModule: WalletAction.GetChainId
665
+ });
608
666
  throw this.EvmWalletException(/* @__PURE__ */ new Error(`Something went wrong while adding ${capitalize(this.wallet || "wallet")} network`), {
609
667
  code: UnspecifiedErrorCode,
610
668
  type: ErrorType.WalletError,
@@ -614,7 +672,7 @@ var EvmWallet = class extends BaseConcreteStrategy {
614
672
  let currentChainId;
615
673
  try {
616
674
  currentChainId = await ethereum.request({ method: "eth_chainId" });
617
- } catch (_unused3) {
675
+ } catch (_unused2) {
618
676
  throw this.EvmWalletException(/* @__PURE__ */ new Error(`Failed to get current chain ID from ${capitalize(this.wallet || "wallet")}`), {
619
677
  code: UnspecifiedErrorCode,
620
678
  type: ErrorType.WalletError,
@@ -629,10 +687,7 @@ var EvmWallet = class extends BaseConcreteStrategy {
629
687
  if (currentChainId.toLowerCase() !== chainIdHex.toLowerCase()) try {
630
688
  await switchEthereumChainWithTimeout(ethereum, chainIdHex, TIMEOUT_MS);
631
689
  } catch (postAddError) {
632
- var _postAddError$code, _postAddError$data;
633
- const postAddRawCode = (_postAddError$code = postAddError === null || postAddError === void 0 ? void 0 : postAddError.code) !== null && _postAddError$code !== void 0 ? _postAddError$code : postAddError === null || postAddError === void 0 || (_postAddError$data = postAddError.data) === null || _postAddError$data === void 0 || (_postAddError$data = _postAddError$data.originalError) === null || _postAddError$data === void 0 ? void 0 : _postAddError$data.code;
634
- const postAddParsed = postAddRawCode != null ? Number(postAddRawCode) : NaN;
635
- if ((!isNaN(postAddParsed) ? postAddParsed : void 0) === 4001) throw this.EvmWalletException(/* @__PURE__ */ new Error(`${capitalize(this.wallet || "wallet")} chain switch after add was rejected`), {
690
+ if (extractNormalizedErrorCode(postAddError) === EvmWalletProviderErrorCode.UserRejectedRequest) throw this.EvmWalletException(/* @__PURE__ */ new Error(`${capitalize(this.wallet || "wallet")} chain switch after add was rejected`), {
636
691
  code: UnspecifiedErrorCode,
637
692
  type: ErrorType.WalletError,
638
693
  contextModule: WalletAction.GetChainId
@@ -646,17 +701,15 @@ var EvmWallet = class extends BaseConcreteStrategy {
646
701
  }
647
702
  }
648
703
  async getEthereum() {
649
- const evmProvider = this.evmProviders[this.wallet];
650
- if (evmProvider) return evmProvider;
651
- const backUpProvider = this.wallet === Wallet.Metamask ? await getMetamaskProvider() : this.wallet === Wallet.Rabby ? await getRabbyProvider() : this.wallet === Wallet.Phantom ? await getPhantomProvider() : this.wallet === Wallet.BitGet ? await getBitGetProvider() : this.wallet === Wallet.OkxWallet ? await getOkxWalletProvider() : this.wallet === Wallet.TrustWallet ? await getTrustWalletProvider() : this.wallet === Wallet.Rainbow ? await getRainbowProvider() : this.wallet === Wallet.KeplrEvm ? await getKeplrEvmProvider() : void 0;
652
- if (!backUpProvider) throw this.EvmWalletException(/* @__PURE__ */ new Error(`Please install the ${this.wallet} wallet extension.`), {
704
+ const provider = await getEvmProviderWithFallback(this.wallet, { eip6963Providers: this.evmProviders });
705
+ if (!provider) throw this.EvmWalletException(/* @__PURE__ */ new Error(`Please install the ${this.wallet} wallet extension.`), {
653
706
  code: UnspecifiedErrorCode,
654
707
  type: ErrorType.WalletNotInstalledError,
655
708
  contextModule: WalletAction.GetAccounts
656
709
  });
657
- return backUpProvider;
710
+ return provider;
658
711
  }
659
712
  };
660
713
 
661
714
  //#endregion
662
- export { EvmWallet as EvmWalletStrategy, getBitGetProvider, getEvmProvider, getKeplrEvmProvider, getMetamaskProvider, getOkxWalletProvider, getPhantomProvider, getRabbyProvider, getRainbowProvider, getTrustWalletProvider, switchEthereumChainWithTimeout, updateEvmNetwork };
715
+ export { EvmWallet as EvmWalletStrategy, extractNormalizedErrorCode, getBitGetProvider, getEvmProvider, getKeplrEvmProvider, getMetamaskProvider, getOkxWalletProvider, getPhantomProvider, getRabbyProvider, getRainbowProvider, getTrustWalletProvider, isUnrecognizedChainError, switchEthereumChainWithTimeout, updateEvmNetwork };