@sodax/wallet-sdk-react 0.0.1-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +233 -0
  3. package/dist/index.cjs +1589 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +15970 -0
  6. package/dist/index.d.ts +15970 -0
  7. package/dist/index.mjs +1513 -0
  8. package/dist/index.mjs.map +1 -0
  9. package/package.json +74 -0
  10. package/src/SodaxWalletProvider.tsx +55 -0
  11. package/src/actions/getXChainType.ts +10 -0
  12. package/src/actions/getXService.ts +25 -0
  13. package/src/actions/index.ts +2 -0
  14. package/src/assets/wallets/hana.svg +6 -0
  15. package/src/assets/wallets/havah.svg +76 -0
  16. package/src/assets/wallets/keplr.svg +30 -0
  17. package/src/assets/wallets/metamask.svg +60 -0
  18. package/src/assets/wallets/phantom.svg +4 -0
  19. package/src/assets/wallets/sui.svg +20 -0
  20. package/src/constants/index.ts +1 -0
  21. package/src/constants/xChains.ts +164 -0
  22. package/src/core/XConnector.ts +54 -0
  23. package/src/core/XService.ts +91 -0
  24. package/src/core/index.ts +2 -0
  25. package/src/hooks/index.ts +11 -0
  26. package/src/hooks/useEthereumChainId.ts +36 -0
  27. package/src/hooks/useEvmSwitchChain.ts +92 -0
  28. package/src/hooks/useWalletProvider.ts +149 -0
  29. package/src/hooks/useWalletProviderOptions.ts +51 -0
  30. package/src/hooks/useXAccount.ts +51 -0
  31. package/src/hooks/useXAccounts.ts +56 -0
  32. package/src/hooks/useXBalances.ts +66 -0
  33. package/src/hooks/useXConnect.ts +119 -0
  34. package/src/hooks/useXConnection.ts +72 -0
  35. package/src/hooks/useXConnectors.ts +56 -0
  36. package/src/hooks/useXDisconnect.ts +65 -0
  37. package/src/hooks/useXService.ts +8 -0
  38. package/src/index.ts +18 -0
  39. package/src/types/index.ts +44 -0
  40. package/src/useXWagmiStore.tsx +164 -0
  41. package/src/utils/index.ts +33 -0
  42. package/src/xchains/evm/EvmXConnector.ts +27 -0
  43. package/src/xchains/evm/EvmXService.ts +189 -0
  44. package/src/xchains/evm/index.ts +2 -0
  45. package/src/xchains/icon/IconHanaXConnector.ts +39 -0
  46. package/src/xchains/icon/IconXService.ts +115 -0
  47. package/src/xchains/icon/iconex/index.tsx +46 -0
  48. package/src/xchains/icon/index.ts +2 -0
  49. package/src/xchains/injective/InjectiveKelprXConnector.ts +37 -0
  50. package/src/xchains/injective/InjectiveMetamaskXConnector.ts +40 -0
  51. package/src/xchains/injective/InjectiveXService.ts +71 -0
  52. package/src/xchains/injective/index.ts +4 -0
  53. package/src/xchains/injective/utils.ts +17 -0
  54. package/src/xchains/solana/SolanaXConnector.ts +26 -0
  55. package/src/xchains/solana/SolanaXService.ts +50 -0
  56. package/src/xchains/solana/hooks/useAnchorProvider.tsx +9 -0
  57. package/src/xchains/solana/index.ts +2 -0
  58. package/src/xchains/stellar/CustomSorobanServer.ts +93 -0
  59. package/src/xchains/stellar/StellarWalletsKitXConnector.ts +45 -0
  60. package/src/xchains/stellar/StellarXService.ts +61 -0
  61. package/src/xchains/stellar/index.tsx +2 -0
  62. package/src/xchains/stellar/useStellarXConnectors.ts +30 -0
  63. package/src/xchains/stellar/utils.ts +49 -0
  64. package/src/xchains/sui/SuiXConnector.ts +28 -0
  65. package/src/xchains/sui/SuiXService.ts +56 -0
  66. package/src/xchains/sui/index.ts +2 -0
package/dist/index.mjs ADDED
@@ -0,0 +1,1513 @@
1
+ import { erc20Abi, defineChain } from 'viem';
2
+ import { getPublicClient, getWalletClient } from 'wagmi/actions';
3
+ import { http, createConfig, useConnections, useAccount, useConnect, useConnectors, useDisconnect, usePublicClient, useWalletClient, useSwitchChain, WagmiProvider } from 'wagmi';
4
+ import { mainnet, lightlinkPhoenix, nibiru as nibiru$1, polygon as polygon$1, optimism as optimism$1, sonic as sonic$1, bsc as bsc$1, base as base$1, arbitrum as arbitrum$1, avalanche as avalanche$1 } from 'wagmi/chains';
5
+ import { LIGHTLINK_MAINNET_CHAIN_ID, HYPEREVM_MAINNET_CHAIN_ID, NIBIRU_MAINNET_CHAIN_ID, POLYGON_MAINNET_CHAIN_ID, OPTIMISM_MAINNET_CHAIN_ID, SONIC_MAINNET_CHAIN_ID, BSC_MAINNET_CHAIN_ID, BASE_MAINNET_CHAIN_ID, ARBITRUM_MAINNET_CHAIN_ID, AVALANCHE_MAINNET_CHAIN_ID } from '@sodax/types';
6
+ import { IconService, Builder, Converter } from 'icon-sdk-js';
7
+ import { getNetworkEndpoints, Network } from '@injectivelabs/networks';
8
+ import { IndexerGrpcAccountPortfolioApi, ChainGrpcWasmApi, getInjectiveAddress } from '@injectivelabs/sdk-ts';
9
+ import { ChainId, EvmChainId } from '@injectivelabs/ts-types';
10
+ import { EvmWalletStrategy } from '@injectivelabs/wallet-evm';
11
+ import { BaseWalletStrategy, MsgBroadcaster } from '@injectivelabs/wallet-core';
12
+ import { Wallet, isEvmBrowserWallet } from '@injectivelabs/wallet-base';
13
+ import { isCosmosWalletInstalled } from '@injectivelabs/wallet-cosmos';
14
+ import { PublicKey } from '@solana/web3.js';
15
+ import { getAssociatedTokenAddressSync, getAccount } from '@solana/spl-token';
16
+ import { StellarWalletsKit, allowAllModules, FREIGHTER_ID, WalletNetwork } from '@creit.tech/stellar-wallets-kit';
17
+ import * as StellarSdk from '@stellar/stellar-sdk';
18
+ import { SorobanRpc, Address, Contract, TimeoutInfinite, scValToBigInt, xdr } from '@stellar/stellar-sdk';
19
+ import React3, { useEffect, useMemo, useCallback } from 'react';
20
+ import { useSuiClient, useCurrentWallet, useCurrentAccount, useConnectWallet, useWallets, useDisconnectWallet, SuiClientProvider, WalletProvider } from '@mysten/dapp-kit';
21
+ import { useConnection, useWallet, ConnectionProvider, WalletProvider as WalletProvider$1 } from '@solana/wallet-adapter-react';
22
+ import { create } from 'zustand';
23
+ import { persist, createJSONStorage } from 'zustand/middleware';
24
+ import { immer } from 'zustand/middleware/immer';
25
+ import { AnchorProvider } from '@coral-xyz/anchor';
26
+ import { useMutation, useQuery, keepPreviousData } from '@tanstack/react-query';
27
+ import { mainnet as mainnet$1 } from 'viem/chains';
28
+ import { SolanaWalletProvider, StellarWalletProvider, InjectiveWalletProvider, IconWalletProvider, SuiWalletProvider, EvmWalletProvider } from '@sodax/wallet-sdk-core';
29
+ import { getFullnodeUrl } from '@mysten/sui/client';
30
+ import { UnsafeBurnerWalletAdapter } from '@solana/wallet-adapter-wallets';
31
+
32
+ // src/constants/xChains.ts
33
+ var icon = {
34
+ id: 1,
35
+ name: "ICON",
36
+ xChainId: "0x1.icon",
37
+ xChainType: "ICON",
38
+ testnet: false
39
+ };
40
+ var avalanche = {
41
+ id: 43114,
42
+ name: "Avalanche",
43
+ xChainId: "0xa86a.avax",
44
+ xChainType: "EVM",
45
+ testnet: false
46
+ };
47
+ var bsc = {
48
+ id: 56,
49
+ name: "BNB Chain",
50
+ xChainId: "0x38.bsc",
51
+ xChainType: "EVM",
52
+ testnet: false
53
+ };
54
+ var arbitrum = {
55
+ id: 42161,
56
+ name: "Arbitrum",
57
+ xChainId: "0xa4b1.arbitrum",
58
+ xChainType: "EVM",
59
+ testnet: false
60
+ };
61
+ var base = {
62
+ id: 8453,
63
+ name: "Base",
64
+ xChainId: "0x2105.base",
65
+ xChainType: "EVM",
66
+ testnet: false
67
+ };
68
+ var injective = {
69
+ id: "injective-1",
70
+ name: "Injective",
71
+ xChainId: "injective-1",
72
+ xChainType: "INJECTIVE",
73
+ testnet: false
74
+ };
75
+ var stellar = {
76
+ id: "stellar",
77
+ name: "Stellar",
78
+ xChainId: "stellar",
79
+ xChainType: "STELLAR",
80
+ testnet: false
81
+ };
82
+ var sui = {
83
+ id: "sui",
84
+ name: "Sui",
85
+ xChainId: "sui",
86
+ xChainType: "SUI",
87
+ testnet: false
88
+ };
89
+ var solana = {
90
+ id: "solana",
91
+ name: "Solana",
92
+ xChainId: "solana",
93
+ xChainType: "SOLANA",
94
+ testnet: false
95
+ };
96
+ var optimism = {
97
+ id: 10,
98
+ name: "Optimism",
99
+ xChainId: "0xa.optimism",
100
+ xChainType: "EVM",
101
+ testnet: false
102
+ };
103
+ var sonic = {
104
+ id: 146,
105
+ name: "Sonic",
106
+ xChainId: "sonic",
107
+ xChainType: "EVM",
108
+ testnet: false
109
+ };
110
+ var polygon = {
111
+ id: 137,
112
+ name: "Polygon",
113
+ xChainId: "0x89.polygon",
114
+ xChainType: "EVM",
115
+ testnet: false
116
+ };
117
+ var nibiru = {
118
+ id: 6900,
119
+ name: "Nibiru",
120
+ xChainId: "nibiru",
121
+ xChainType: "EVM",
122
+ testnet: false
123
+ };
124
+ var hyper = {
125
+ id: 999,
126
+ name: "HyperEVM",
127
+ xChainId: "hyper",
128
+ xChainType: "EVM",
129
+ testnet: false
130
+ };
131
+ var lightlink = {
132
+ id: 1890,
133
+ name: "Lightlink",
134
+ xChainId: "lightlink",
135
+ xChainType: "EVM",
136
+ testnet: false
137
+ };
138
+ var xChainMap = {
139
+ "0x1.icon": icon,
140
+ "0xa4b1.arbitrum": arbitrum,
141
+ "0xa86a.avax": avalanche,
142
+ "0x38.bsc": bsc,
143
+ "0x2105.base": base,
144
+ "0xa.optimism": optimism,
145
+ "injective-1": injective,
146
+ stellar,
147
+ sui,
148
+ solana,
149
+ sonic,
150
+ "0x89.polygon": polygon,
151
+ nibiru,
152
+ hyper,
153
+ lightlink
154
+ };
155
+ var xChains = Object.values(xChainMap);
156
+
157
+ // src/actions/getXChainType.ts
158
+ function getXChainType(xChainId) {
159
+ if (!xChainId) {
160
+ return void 0;
161
+ }
162
+ return xChainMap[xChainId].xChainType;
163
+ }
164
+
165
+ // src/actions/getXService.ts
166
+ function getXService(xChainType) {
167
+ switch (xChainType) {
168
+ case "EVM":
169
+ return EvmXService.getInstance();
170
+ case "SUI":
171
+ return SuiXService.getInstance();
172
+ case "SOLANA":
173
+ return SolanaXService.getInstance();
174
+ case "ICON":
175
+ return IconXService.getInstance();
176
+ case "INJECTIVE":
177
+ return InjectiveXService.getInstance();
178
+ case "STELLAR":
179
+ return StellarXService.getInstance();
180
+ default:
181
+ throw new Error(`Unsupported chain type: ${xChainType}`);
182
+ }
183
+ }
184
+
185
+ // src/core/XService.ts
186
+ var XService = class {
187
+ constructor(xChainType) {
188
+ /** Available wallet connectors for this chain */
189
+ this.xConnectors = [];
190
+ this.xChainType = xChainType;
191
+ }
192
+ /**
193
+ * Gets the balance of a specific token for an address
194
+ * @param address The wallet address to check
195
+ * @param xToken The token to get the balance for
196
+ * @param xChainId The chain ID to query
197
+ * @returns Promise resolving to the token balance as a bigint
198
+ */
199
+ async getBalance(address, xToken, xChainId) {
200
+ return 0n;
201
+ }
202
+ /**
203
+ * Gets balances for multiple tokens for an address
204
+ * @param address The wallet address to check
205
+ * @param xTokens Array of tokens to get balances for
206
+ * @param xChainId The chain ID to query
207
+ * @returns Promise resolving to object mapping token addresses to balances
208
+ */
209
+ async getBalances(address, xTokens, xChainId) {
210
+ if (!address) return {};
211
+ const balancePromises = xTokens.map(async (xToken) => {
212
+ const balance = await this.getBalance(address, xToken, xChainId);
213
+ return { address: xToken.address, balance };
214
+ });
215
+ const balances = await Promise.all(balancePromises);
216
+ return balances.reduce((acc, { address: address2, balance }) => {
217
+ acc[address2] = balance;
218
+ return acc;
219
+ }, {});
220
+ }
221
+ /**
222
+ * Gets all available connectors for this chain
223
+ */
224
+ getXConnectors() {
225
+ return this.xConnectors;
226
+ }
227
+ /**
228
+ * Sets the available connectors for this chain
229
+ */
230
+ setXConnectors(xConnectors) {
231
+ this.xConnectors = xConnectors;
232
+ }
233
+ /**
234
+ * Gets a specific connector by its ID
235
+ * @param xConnectorId The connector ID to look up
236
+ * @returns The matching connector or undefined if not found
237
+ */
238
+ getXConnectorById(xConnectorId) {
239
+ return this.getXConnectors().find((xConnector) => xConnector.id === xConnectorId);
240
+ }
241
+ };
242
+
243
+ // src/core/XConnector.ts
244
+ var XConnector = class {
245
+ constructor(xChainType, name, id) {
246
+ this.xChainType = xChainType;
247
+ this.name = name;
248
+ this._id = id;
249
+ }
250
+ /** Get the unique identifier for this connector */
251
+ get id() {
252
+ return this._id;
253
+ }
254
+ /** Get the optional icon URL for this wallet provider */
255
+ get icon() {
256
+ return this._icon;
257
+ }
258
+ };
259
+
260
+ // src/utils/index.ts
261
+ var isNativeToken = (xToken) => {
262
+ const nativeAddresses = [
263
+ "cx0000000000000000000000000000000000000000",
264
+ "0x0000000000000000000000000000000000000000",
265
+ "inj",
266
+ "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI",
267
+ "hx0000000000000000000000000000000000000000",
268
+ "11111111111111111111111111111111",
269
+ // solana
270
+ "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA"
271
+ // stellar,
272
+ ];
273
+ return nativeAddresses.includes(xToken.address);
274
+ };
275
+ var getWagmiChainId = (xChainId) => {
276
+ const xChainMap2 = {
277
+ "0xa869.fuji": 43113,
278
+ "sonic-blaze": 57054,
279
+ sonic: 146,
280
+ "0xa86a.avax": 43114,
281
+ "0x38.bsc": 56,
282
+ "0xa4b1.arbitrum": 42161,
283
+ "0x2105.base": 8453,
284
+ "0xa.optimism": 10,
285
+ "0x89.polygon": 137,
286
+ hyper: 999,
287
+ lightlink: 1890
288
+ };
289
+ return xChainMap2[xChainId] ?? 0;
290
+ };
291
+ var hyper2 = /* @__PURE__ */ defineChain({
292
+ id: 999,
293
+ name: "HyperEVM",
294
+ nativeCurrency: {
295
+ decimals: 18,
296
+ name: "HYPE",
297
+ symbol: "HYPE"
298
+ },
299
+ rpcUrls: {
300
+ default: { http: ["https://rpc.hyperliquid.xyz/evm"] }
301
+ },
302
+ blockExplorers: {
303
+ default: {
304
+ name: "HyperEVMScan",
305
+ url: "https://hyperevmscan.io/"
306
+ }
307
+ },
308
+ contracts: {
309
+ multicall3: {
310
+ address: "0xcA11bde05977b3631167028862bE2a173976CA11",
311
+ blockCreated: 13051
312
+ }
313
+ }
314
+ });
315
+ var evmChainMap = {
316
+ [AVALANCHE_MAINNET_CHAIN_ID]: avalanche$1,
317
+ [ARBITRUM_MAINNET_CHAIN_ID]: arbitrum$1,
318
+ [BASE_MAINNET_CHAIN_ID]: base$1,
319
+ [BSC_MAINNET_CHAIN_ID]: bsc$1,
320
+ [SONIC_MAINNET_CHAIN_ID]: sonic$1,
321
+ [OPTIMISM_MAINNET_CHAIN_ID]: optimism$1,
322
+ [POLYGON_MAINNET_CHAIN_ID]: polygon$1,
323
+ [NIBIRU_MAINNET_CHAIN_ID]: nibiru$1,
324
+ [HYPEREVM_MAINNET_CHAIN_ID]: hyper2,
325
+ [LIGHTLINK_MAINNET_CHAIN_ID]: lightlinkPhoenix
326
+ };
327
+ var getWagmiConfig = (chains) => {
328
+ const mappedChains = chains.map((chain) => evmChainMap[chain]);
329
+ const finalChains = mappedChains.length > 0 ? mappedChains : [mainnet];
330
+ const transports = finalChains.reduce(
331
+ (acc, chain) => {
332
+ acc[chain.id] = http();
333
+ return acc;
334
+ },
335
+ {}
336
+ );
337
+ return createConfig({
338
+ chains: finalChains,
339
+ transports
340
+ // ssr: true,
341
+ });
342
+ };
343
+ var EvmXService = class _EvmXService extends XService {
344
+ constructor() {
345
+ super("EVM");
346
+ }
347
+ getXConnectors() {
348
+ return [];
349
+ }
350
+ static getInstance() {
351
+ if (!_EvmXService.instance) {
352
+ _EvmXService.instance = new _EvmXService();
353
+ }
354
+ return _EvmXService.instance;
355
+ }
356
+ setConfig(config) {
357
+ this.config = config;
358
+ }
359
+ getPublicClient(chainId) {
360
+ if (!this.config) {
361
+ throw new Error("EvmXService: config is not initialized yet");
362
+ }
363
+ return getPublicClient(getWagmiConfig(this.config.chains), { chainId });
364
+ }
365
+ async getWalletClient(chainId) {
366
+ if (!this.config) {
367
+ throw new Error("EvmXService: config is not initialized yet");
368
+ }
369
+ return await getWalletClient(getWagmiConfig(this.config.chains), { chainId });
370
+ }
371
+ async getBalance(address, xToken, xChainId) {
372
+ if (!address) return 0n;
373
+ const chainId = getWagmiChainId(xChainId);
374
+ if (isNativeToken(xToken)) {
375
+ const balance = await this.getPublicClient(chainId)?.getBalance({ address });
376
+ return balance || 0n;
377
+ }
378
+ throw new Error(`Unsupported token: ${xToken.symbol}`);
379
+ }
380
+ async getBalances(address, xTokens, xChainId) {
381
+ if (!address) return {};
382
+ const balancePromises = xTokens.filter((xToken) => isNativeToken(xToken)).map(async (xToken) => {
383
+ const balance = await this.getBalance(address, xToken, xChainId);
384
+ return { symbol: xToken.symbol, address: xToken.address, balance };
385
+ });
386
+ const balances = await Promise.all(balancePromises);
387
+ const tokenMap = balances.reduce((map, { address: address2, balance }) => {
388
+ if (balance) map[address2] = balance;
389
+ return map;
390
+ }, {});
391
+ const nonNativeXTokens = xTokens.filter((xToken) => !isNativeToken(xToken));
392
+ const result = await this.getPublicClient(getWagmiChainId(xChainId))?.multicall({
393
+ contracts: nonNativeXTokens.map((token) => ({
394
+ abi: erc20Abi,
395
+ address: token.address,
396
+ functionName: "balanceOf",
397
+ args: [address],
398
+ chainId: getWagmiChainId(xChainId)
399
+ }))
400
+ });
401
+ return nonNativeXTokens.map((token, index) => ({
402
+ symbol: token.symbol,
403
+ address: token.address,
404
+ balance: result?.[index]?.result?.toString() || "0"
405
+ })).reduce((acc, balance) => {
406
+ acc[balance.address] = balance.balance;
407
+ return acc;
408
+ }, tokenMap);
409
+ }
410
+ };
411
+
412
+ // src/xchains/evm/EvmXConnector.ts
413
+ var EvmXConnector = class extends XConnector {
414
+ constructor(connector) {
415
+ super("EVM", connector.name, connector.id);
416
+ this.connector = connector;
417
+ }
418
+ async connect() {
419
+ return;
420
+ }
421
+ async disconnect() {
422
+ return;
423
+ }
424
+ get id() {
425
+ return this.connector.id;
426
+ }
427
+ get icon() {
428
+ return this.connector.icon;
429
+ }
430
+ };
431
+ var CHAIN_INFO = {
432
+ [1 /* MAINNET */]: {
433
+ APIEndpoint: "https://ctz.solidwallet.io/api/v3"}
434
+ };
435
+ var IconXService = class _IconXService extends XService {
436
+ constructor() {
437
+ super("ICON");
438
+ this.iconService = new IconService(
439
+ new IconService.HttpProvider(CHAIN_INFO[1 /* MAINNET */].APIEndpoint)
440
+ );
441
+ }
442
+ static getInstance() {
443
+ if (!_IconXService.instance) {
444
+ _IconXService.instance = new _IconXService();
445
+ }
446
+ return _IconXService.instance;
447
+ }
448
+ async getAggregateData(requireSuccess, calls) {
449
+ const rawTx = new Builder.CallBuilder().to("cxa4aa9185e23558cff990f494c1fd2845f6cbf741").method("tryAggregate").params({ requireSuccess: Converter.toHex(requireSuccess ? 1 : 0), calls }).build();
450
+ try {
451
+ const result = await this.iconService.call(rawTx).execute();
452
+ const aggs = result["returnData"];
453
+ const data = aggs.map((agg) => {
454
+ if (agg["success"] === "0x0") {
455
+ return null;
456
+ }
457
+ return agg["returnData"];
458
+ });
459
+ return data;
460
+ } catch (err) {
461
+ console.error(err);
462
+ return Array(calls.length).fill(null);
463
+ }
464
+ }
465
+ async getBalances(address, xTokens, xChainId) {
466
+ if (!address) return {};
467
+ const balances = {};
468
+ const nativeXToken = xTokens.find((xToken) => isNativeToken(xToken));
469
+ const nonNativeXTokens = xTokens.filter((xToken) => !isNativeToken(xToken));
470
+ if (nativeXToken) {
471
+ const balance = await this.iconService.getBalance(address).execute();
472
+ balances[nativeXToken.address] = BigInt(balance.toFixed());
473
+ }
474
+ const cds = nonNativeXTokens.map((token) => {
475
+ return {
476
+ target: token.address,
477
+ method: "balanceOf",
478
+ params: [address]
479
+ };
480
+ });
481
+ const data = await this.getAggregateData(
482
+ false,
483
+ cds.filter((cd) => cd.target.startsWith("cx"))
484
+ );
485
+ return nonNativeXTokens.reduce((agg, token, idx) => {
486
+ const balance = data[idx];
487
+ balances[token.address] = BigInt(balance);
488
+ return agg;
489
+ }, balances);
490
+ }
491
+ };
492
+
493
+ // src/xchains/icon/iconex/index.tsx
494
+ var ICONEX_RELAY_RESPONSE = "ICONEX_RELAY_RESPONSE";
495
+ var ICONEX_RELAY_REQUEST = "ICONEX_RELAY_REQUEST";
496
+ var request = (event) => {
497
+ return new Promise((resolve, reject) => {
498
+ const handler = (evt) => {
499
+ window.removeEventListener(ICONEX_RELAY_RESPONSE, handler);
500
+ resolve(evt.detail);
501
+ };
502
+ window.addEventListener(ICONEX_RELAY_RESPONSE, handler);
503
+ window.dispatchEvent(
504
+ new CustomEvent(ICONEX_RELAY_REQUEST, {
505
+ detail: event
506
+ })
507
+ );
508
+ });
509
+ };
510
+
511
+ // src/xchains/icon/IconHanaXConnector.ts
512
+ var IconHanaXConnector = class extends XConnector {
513
+ constructor() {
514
+ super("ICON", "Hana Wallet", "hana");
515
+ }
516
+ async connect() {
517
+ const { hanaWallet } = window;
518
+ if (window && !hanaWallet && !hanaWallet?.isAvailable) {
519
+ window.open("https://chromewebstore.google.com/detail/hana-wallet/jfdlamikmbghhapbgfoogdffldioobgl", "_blank");
520
+ return;
521
+ }
522
+ const detail = await request({
523
+ type: "REQUEST_ADDRESS" /* REQUEST_ADDRESS */
524
+ });
525
+ if (detail?.type === "RESPONSE_ADDRESS" /* RESPONSE_ADDRESS */) {
526
+ return {
527
+ address: detail?.payload,
528
+ xChainType: this.xChainType
529
+ };
530
+ }
531
+ return void 0;
532
+ }
533
+ async disconnect() {
534
+ console.log("HanaIconXConnector disconnected");
535
+ }
536
+ get icon() {
537
+ return "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/hana.svg";
538
+ }
539
+ };
540
+ var InjectiveXService = class _InjectiveXService extends XService {
541
+ constructor() {
542
+ super("INJECTIVE");
543
+ const endpoints = getNetworkEndpoints(Network.Mainnet);
544
+ this.walletStrategy = new BaseWalletStrategy({
545
+ chainId: ChainId.Mainnet,
546
+ strategies: {
547
+ [Wallet.Metamask]: new EvmWalletStrategy({
548
+ chainId: ChainId.Mainnet,
549
+ wallet: Wallet.Metamask,
550
+ evmOptions: {
551
+ evmChainId: EvmChainId.Mainnet,
552
+ rpcUrl: mainnet.rpcUrls.default.http[0]
553
+ }
554
+ })
555
+ // [Wallet.Keplr]: new CosmosWalletStrategy({
556
+ // chainId: InjectiveChainId.Mainnet,
557
+ // wallet: Wallet.Keplr,
558
+ // }),
559
+ }
560
+ });
561
+ this.indexerGrpcAccountPortfolioApi = new IndexerGrpcAccountPortfolioApi(endpoints.indexer);
562
+ this.chainGrpcWasmApi = new ChainGrpcWasmApi(endpoints.grpc);
563
+ this.msgBroadcaster = new MsgBroadcaster({
564
+ walletStrategy: this.walletStrategy,
565
+ network: Network.Mainnet,
566
+ endpoints
567
+ });
568
+ }
569
+ static getInstance() {
570
+ if (!_InjectiveXService.instance) {
571
+ _InjectiveXService.instance = new _InjectiveXService();
572
+ }
573
+ return _InjectiveXService.instance;
574
+ }
575
+ async getBalance(address, xToken) {
576
+ if (!address) return 0n;
577
+ const portfolio = await this.indexerGrpcAccountPortfolioApi.fetchAccountPortfolioBalances(address);
578
+ const xTokenAddress = xToken.address;
579
+ const balance = portfolio.bankBalancesList.find((_balance) => _balance.denom === xTokenAddress);
580
+ if (balance) {
581
+ return BigInt(balance.amount);
582
+ }
583
+ return 0n;
584
+ }
585
+ };
586
+ var InjectiveKelprXConnector = class extends XConnector {
587
+ constructor() {
588
+ super("INJECTIVE", "Keplr", "keplr");
589
+ }
590
+ getXService() {
591
+ return InjectiveXService.getInstance();
592
+ }
593
+ async connect() {
594
+ if (!isCosmosWalletInstalled(Wallet.Keplr)) {
595
+ window.open("https://chrome.google.com/webstore/detail/keplr/dmkamcknogkgcdfhhbddcghachkejeap?hl=en", "_blank");
596
+ return;
597
+ }
598
+ this.getXService().walletStrategy.setWallet(Wallet.Keplr);
599
+ const addresses = await this.getXService().walletStrategy.getAddresses();
600
+ return {
601
+ address: addresses?.[0],
602
+ xChainType: this.xChainType
603
+ };
604
+ }
605
+ async disconnect() {
606
+ }
607
+ get icon() {
608
+ return "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/keplr.svg";
609
+ }
610
+ };
611
+ var InjectiveMetamaskXConnector = class extends XConnector {
612
+ constructor() {
613
+ super("INJECTIVE", "MetaMask", "metamask");
614
+ }
615
+ getXService() {
616
+ return InjectiveXService.getInstance();
617
+ }
618
+ async connect() {
619
+ if (!isEvmBrowserWallet(Wallet.Metamask)) {
620
+ window.open("https://chromewebstore.google.com/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en", "_blank");
621
+ return;
622
+ }
623
+ this.getXService().walletStrategy.setWallet(Wallet.Metamask);
624
+ const addresses = await this.getXService().walletStrategy.getAddresses();
625
+ const injectiveAddresses = addresses.map(getInjectiveAddress);
626
+ return {
627
+ address: injectiveAddresses?.[0],
628
+ xChainType: this.xChainType
629
+ };
630
+ }
631
+ async disconnect() {
632
+ await this.getXService().walletStrategy.disconnect();
633
+ }
634
+ get icon() {
635
+ return "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/metamask.svg";
636
+ }
637
+ };
638
+
639
+ // src/xchains/injective/utils.ts
640
+ var switchEthereumChain = async (chainId) => {
641
+ const metamaskProvider = window.ethereum;
642
+ await Promise.race([
643
+ metamaskProvider.request({
644
+ method: "wallet_switchEthereumChain",
645
+ params: [{ chainId: `0x${chainId}` }]
646
+ }),
647
+ new Promise(
648
+ (resolve) => metamaskProvider.on("change", ({ chain }) => {
649
+ if (chain?.id === chainId) {
650
+ resolve();
651
+ }
652
+ })
653
+ )
654
+ ]);
655
+ };
656
+ var SolanaXService = class _SolanaXService extends XService {
657
+ constructor() {
658
+ super("SOLANA");
659
+ }
660
+ static getInstance() {
661
+ if (!_SolanaXService.instance) {
662
+ _SolanaXService.instance = new _SolanaXService();
663
+ }
664
+ return _SolanaXService.instance;
665
+ }
666
+ async getBalance(address, xToken) {
667
+ if (!address) return BigInt(0);
668
+ const connection = this.connection;
669
+ if (!connection) {
670
+ throw new Error("Connection is not initialized");
671
+ }
672
+ try {
673
+ if (isNativeToken(xToken)) {
674
+ const newBalance = await connection.getBalance(new PublicKey(address));
675
+ return BigInt(newBalance);
676
+ }
677
+ const tokenAccountPubkey = getAssociatedTokenAddressSync(new PublicKey(xToken.address), new PublicKey(address));
678
+ const tokenAccount = await getAccount(connection, tokenAccountPubkey);
679
+ return BigInt(tokenAccount.amount);
680
+ } catch (e) {
681
+ console.log("error", e);
682
+ }
683
+ return BigInt(0);
684
+ }
685
+ };
686
+
687
+ // src/xchains/solana/SolanaXConnector.ts
688
+ var SolanaXConnector = class extends XConnector {
689
+ constructor(wallet) {
690
+ super("SOLANA", wallet?.adapter.name, wallet?.adapter.name);
691
+ this.wallet = wallet;
692
+ }
693
+ getXService() {
694
+ return SolanaXService.getInstance();
695
+ }
696
+ async connect() {
697
+ return;
698
+ }
699
+ async disconnect() {
700
+ }
701
+ get icon() {
702
+ return this.wallet?.adapter.icon;
703
+ }
704
+ };
705
+ var CustomSorobanServer = class extends SorobanRpc.Server {
706
+ constructor(serverUrl, customHeaders) {
707
+ super(serverUrl, {
708
+ allowHttp: true
709
+ });
710
+ this.customHeaders = customHeaders;
711
+ }
712
+ async simulateTransaction(tx) {
713
+ const requestOptions = {
714
+ method: "POST",
715
+ headers: {
716
+ "Content-Type": "application/json",
717
+ ...this.customHeaders
718
+ },
719
+ body: JSON.stringify({
720
+ id: 1,
721
+ jsonrpc: "2.0",
722
+ method: "simulateTransaction",
723
+ params: {
724
+ transaction: tx.toXDR()
725
+ }
726
+ })
727
+ };
728
+ const response = await fetch(`${this.serverURL}`, requestOptions);
729
+ if (!response.ok) {
730
+ throw new Error(`HTTP error simulating TX! status: ${response.status}`);
731
+ }
732
+ return response.json().then((json) => json.result);
733
+ }
734
+ async sendTransaction(tx) {
735
+ const requestOptions = {
736
+ method: "POST",
737
+ headers: {
738
+ "Content-Type": "application/json",
739
+ ...this.customHeaders
740
+ },
741
+ body: JSON.stringify({
742
+ id: 1,
743
+ jsonrpc: "2.0",
744
+ method: "sendTransaction",
745
+ params: {
746
+ transaction: tx.toXDR()
747
+ }
748
+ })
749
+ };
750
+ const response = await fetch(`${this.serverURL}`, requestOptions);
751
+ if (!response.ok) {
752
+ throw new Error(`HTTP error submitting TX! status: ${response.status}`);
753
+ }
754
+ return response.json().then((json) => json.result);
755
+ }
756
+ async getTransaction(hash) {
757
+ const requestOptions = {
758
+ method: "POST",
759
+ headers: {
760
+ "Content-Type": "application/json",
761
+ ...this.customHeaders
762
+ },
763
+ body: JSON.stringify({
764
+ id: 1,
765
+ jsonrpc: "2.0",
766
+ method: "getTransaction",
767
+ params: { hash }
768
+ })
769
+ };
770
+ const response = await fetch(`${this.serverURL}`, requestOptions);
771
+ if (!response.ok) {
772
+ throw new Error(`HTTP error getting TX! status: ${response.status}`);
773
+ }
774
+ return response.json().then((json) => json.result);
775
+ }
776
+ };
777
+ var CustomSorobanServer_default = CustomSorobanServer;
778
+ var accountToScVal = (account) => new Address(account).toScVal();
779
+ var simulateTx = async (tx, server) => {
780
+ const response = await server.simulateTransaction(tx);
781
+ if (response !== void 0) {
782
+ return response;
783
+ }
784
+ throw new Error("cannot simulate transaction");
785
+ };
786
+ var getTokenBalance = async (address, tokenId, txBuilder, server) => {
787
+ const params = [accountToScVal(address)];
788
+ const contract = new Contract(tokenId);
789
+ const tx = txBuilder.addOperation(contract.call("balance", ...params)).setTimeout(TimeoutInfinite).build();
790
+ const result = await simulateTx(tx, server);
791
+ return result.results ? scValToBigInt(xdr.ScVal.fromXDR(result.results[0].xdr, "base64")) : 0n;
792
+ };
793
+
794
+ // src/xchains/stellar/StellarXService.ts
795
+ var StellarXService = class _StellarXService extends XService {
796
+ constructor() {
797
+ super("STELLAR");
798
+ this.walletsKit = new StellarWalletsKit({
799
+ network: WalletNetwork.PUBLIC,
800
+ selectedWalletId: FREIGHTER_ID,
801
+ modules: allowAllModules()
802
+ });
803
+ this.server = new StellarSdk.Horizon.Server("https://horizon.stellar.org", { allowHttp: true });
804
+ this.sorobanServer = new CustomSorobanServer_default("https://rpc.ankr.com/stellar_soroban", {});
805
+ }
806
+ static getInstance() {
807
+ if (!_StellarXService.instance) {
808
+ _StellarXService.instance = new _StellarXService();
809
+ }
810
+ return _StellarXService.instance;
811
+ }
812
+ async getBalance(address, xToken) {
813
+ if (!address) return BigInt(0);
814
+ const stellarAccount = await this.server.loadAccount(address);
815
+ if (xToken.symbol === "XLM") {
816
+ const xlmBalance = stellarAccount.balances.find((balance) => balance.asset_type === "native");
817
+ if (xlmBalance) {
818
+ return BigInt(xlmBalance.balance.replace(".", ""));
819
+ }
820
+ } else {
821
+ try {
822
+ const txBuilder = new StellarSdk.TransactionBuilder(stellarAccount, {
823
+ fee: StellarSdk.BASE_FEE,
824
+ networkPassphrase: StellarSdk.Networks.PUBLIC
825
+ });
826
+ const balance = await getTokenBalance(address, xToken.address, txBuilder, this.sorobanServer);
827
+ return balance;
828
+ } catch (e) {
829
+ console.error(`Error while fetching token on Stellar: ${xToken.symbol}, Error: ${e}`);
830
+ }
831
+ }
832
+ return BigInt(0);
833
+ }
834
+ };
835
+
836
+ // src/xchains/stellar/StellarWalletsKitXConnector.ts
837
+ var StellarWalletsKitXConnector = class extends XConnector {
838
+ constructor(wallet) {
839
+ super("STELLAR", wallet.name, wallet.id);
840
+ this._wallet = wallet;
841
+ }
842
+ getXService() {
843
+ return StellarXService.getInstance();
844
+ }
845
+ async connect() {
846
+ const kit = this.getXService().walletsKit;
847
+ if (!this._wallet) {
848
+ return;
849
+ }
850
+ if (!this._wallet.isAvailable && this._wallet.url) {
851
+ window.open(this._wallet.url, "_blank");
852
+ return;
853
+ }
854
+ kit.setWallet(this._wallet.id);
855
+ const { address } = await kit.getAddress();
856
+ return {
857
+ address,
858
+ xChainType: this.xChainType
859
+ };
860
+ }
861
+ async disconnect() {
862
+ }
863
+ get icon() {
864
+ return this._wallet.icon;
865
+ }
866
+ };
867
+
868
+ // src/xchains/sui/SuiXService.ts
869
+ var SuiXService = class _SuiXService extends XService {
870
+ // TODO: define suiAccount type
871
+ constructor() {
872
+ super("SUI");
873
+ }
874
+ static getInstance() {
875
+ if (!_SuiXService.instance) {
876
+ _SuiXService.instance = new _SuiXService();
877
+ }
878
+ return _SuiXService.instance;
879
+ }
880
+ // getBalance is not used because getBalances uses getAllBalances which returns all balances
881
+ async getBalances(address, xTokens) {
882
+ if (!address) return {};
883
+ try {
884
+ const allBalances = await this.suiClient.getAllBalances({
885
+ owner: address
886
+ });
887
+ const tokenMap = xTokens.reduce((map, xToken) => {
888
+ let coinType = isNativeToken(xToken) ? "0x2::sui::SUI" : xToken.address;
889
+ if (coinType === "0x03917a812fe4a6d6bc779c5ab53f8a80ba741f8af04121193fc44e0f662e2ceb::balanced_dollar::BALANCED_DOLLAR") {
890
+ coinType = "0x3917a812fe4a6d6bc779c5ab53f8a80ba741f8af04121193fc44e0f662e2ceb::balanced_dollar::BALANCED_DOLLAR";
891
+ }
892
+ const balance = allBalances.find((b) => b.coinType === coinType);
893
+ if (balance) map[xToken.address] = balance.totalBalance;
894
+ return map;
895
+ }, {});
896
+ return tokenMap;
897
+ } catch (e) {
898
+ console.log("error", e);
899
+ return {};
900
+ }
901
+ }
902
+ };
903
+
904
+ // src/xchains/sui/SuiXConnector.ts
905
+ var SuiXConnector = class extends XConnector {
906
+ constructor(wallet) {
907
+ super("SUI", wallet?.name, wallet?.name);
908
+ this.wallet = wallet;
909
+ }
910
+ getXService() {
911
+ return SuiXService.getInstance();
912
+ }
913
+ async connect() {
914
+ return;
915
+ }
916
+ async disconnect() {
917
+ }
918
+ get icon() {
919
+ return this.wallet?.icon;
920
+ }
921
+ };
922
+ function useAnchorProvider() {
923
+ const { connection } = useConnection();
924
+ const wallet = useWallet();
925
+ return new AnchorProvider(connection, wallet, { commitment: "confirmed" });
926
+ }
927
+ var useXWagmiStore = create()(
928
+ persist(
929
+ immer((set, get) => ({
930
+ xServices: {},
931
+ xConnections: {},
932
+ setXConnection: (xChainType, xConnection) => {
933
+ set((state) => {
934
+ state.xConnections[xChainType] = xConnection;
935
+ });
936
+ },
937
+ unsetXConnection: (xChainType) => {
938
+ set((state) => {
939
+ delete state.xConnections[xChainType];
940
+ });
941
+ }
942
+ })),
943
+ {
944
+ name: "xwagmi-store",
945
+ storage: createJSONStorage(() => localStorage),
946
+ partialize: (state) => ({ xConnections: state.xConnections }),
947
+ // TODO: better way to handle rehydration of xConnections?
948
+ onRehydrateStorage: (state) => {
949
+ console.log("hydration starts");
950
+ return (state2, error) => {
951
+ if (state2?.xConnections) {
952
+ console.log("rehydrating xConnections", state2.xConnections);
953
+ Object.entries(state2.xConnections).forEach(([xChainType, xConnection]) => {
954
+ const xConnector = getXService(xChainType).getXConnectorById(xConnection.xConnectorId);
955
+ xConnector?.connect();
956
+ });
957
+ }
958
+ if (error) {
959
+ console.log("an error happened during hydration", error);
960
+ } else {
961
+ console.log("hydration finished");
962
+ }
963
+ };
964
+ }
965
+ }
966
+ )
967
+ );
968
+ var initXServices = (config) => {
969
+ const xServices = {};
970
+ Object.keys(config).forEach((key) => {
971
+ const xChainType = key;
972
+ switch (xChainType) {
973
+ case "EVM":
974
+ if (config[xChainType]) {
975
+ xServices[xChainType] = EvmXService.getInstance();
976
+ xServices[xChainType].setXConnectors([]);
977
+ xServices[xChainType].setConfig(config[xChainType]);
978
+ }
979
+ break;
980
+ case "INJECTIVE":
981
+ xServices[xChainType] = InjectiveXService.getInstance();
982
+ xServices[xChainType].setXConnectors([new InjectiveMetamaskXConnector()]);
983
+ break;
984
+ case "STELLAR":
985
+ xServices[xChainType] = StellarXService.getInstance();
986
+ xServices[xChainType].setXConnectors([]);
987
+ break;
988
+ case "SUI":
989
+ xServices[xChainType] = SuiXService.getInstance();
990
+ xServices[xChainType].setXConnectors([]);
991
+ break;
992
+ case "SOLANA":
993
+ xServices[xChainType] = SolanaXService.getInstance();
994
+ xServices[xChainType].setXConnectors([]);
995
+ break;
996
+ case "ICON":
997
+ xServices[xChainType] = IconXService.getInstance();
998
+ xServices[xChainType].setXConnectors([new IconHanaXConnector()]);
999
+ break;
1000
+ }
1001
+ });
1002
+ return xServices;
1003
+ };
1004
+ var initXWagmiStore = (config) => {
1005
+ useXWagmiStore.setState({
1006
+ xServices: initXServices(config)
1007
+ });
1008
+ };
1009
+ var InitXWagmiStore = () => {
1010
+ const suiClient = useSuiClient();
1011
+ useEffect(() => {
1012
+ if (suiClient) {
1013
+ SuiXService.getInstance().suiClient = suiClient;
1014
+ }
1015
+ }, [suiClient]);
1016
+ const { currentWallet: suiWallet } = useCurrentWallet();
1017
+ useEffect(() => {
1018
+ if (suiWallet) {
1019
+ SuiXService.getInstance().suiWallet = suiWallet;
1020
+ }
1021
+ }, [suiWallet]);
1022
+ const suiAccount = useCurrentAccount();
1023
+ useEffect(() => {
1024
+ if (suiAccount) {
1025
+ SuiXService.getInstance().suiAccount = suiAccount;
1026
+ }
1027
+ }, [suiAccount]);
1028
+ const { connection: solanaConnection } = useConnection();
1029
+ const solanaWallet = useWallet();
1030
+ const solanaProvider = useAnchorProvider();
1031
+ useEffect(() => {
1032
+ if (solanaConnection) {
1033
+ SolanaXService.getInstance().connection = solanaConnection;
1034
+ }
1035
+ }, [solanaConnection]);
1036
+ useEffect(() => {
1037
+ if (solanaWallet) {
1038
+ SolanaXService.getInstance().wallet = solanaWallet;
1039
+ }
1040
+ }, [solanaWallet]);
1041
+ useEffect(() => {
1042
+ if (solanaProvider) {
1043
+ SolanaXService.getInstance().provider = solanaProvider;
1044
+ }
1045
+ }, [solanaProvider]);
1046
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null);
1047
+ };
1048
+
1049
+ // src/hooks/useXConnection.ts
1050
+ function useXConnection(xChainType) {
1051
+ const xConnection = useXWagmiStore((state) => xChainType ? state.xConnections?.[xChainType] : void 0);
1052
+ const evmConnections = useConnections();
1053
+ const { address: evmAddress } = useAccount();
1054
+ const suiAccount = useCurrentAccount();
1055
+ const suiCurrentWallet = useCurrentWallet();
1056
+ const solanaWallet = useWallet();
1057
+ const xConnection2 = useMemo(() => {
1058
+ if (!xChainType) {
1059
+ return void 0;
1060
+ }
1061
+ switch (xChainType) {
1062
+ case "EVM":
1063
+ return {
1064
+ xAccount: { address: evmAddress, xChainType },
1065
+ xConnectorId: evmConnections?.[0]?.connector.id
1066
+ };
1067
+ case "SUI":
1068
+ if (suiCurrentWallet.currentWallet && suiCurrentWallet.connectionStatus === "connected") {
1069
+ return {
1070
+ xAccount: { address: suiAccount?.address, xChainType },
1071
+ xConnectorId: suiCurrentWallet.currentWallet.name
1072
+ };
1073
+ }
1074
+ return void 0;
1075
+ case "SOLANA":
1076
+ if (solanaWallet.connected) {
1077
+ return {
1078
+ xAccount: { address: solanaWallet.publicKey?.toString(), xChainType },
1079
+ xConnectorId: `${solanaWallet.wallet?.adapter.name}`
1080
+ };
1081
+ }
1082
+ return void 0;
1083
+ default:
1084
+ return xConnection;
1085
+ }
1086
+ }, [xChainType, xConnection, evmAddress, suiAccount, evmConnections, suiCurrentWallet, solanaWallet]);
1087
+ return xConnection2;
1088
+ }
1089
+
1090
+ // src/hooks/useXAccount.ts
1091
+ function isChainType(chainIdentifier) {
1092
+ return ["ICON", "EVM", "INJECTIVE", "SUI", "STELLAR", "SOLANA"].includes(chainIdentifier);
1093
+ }
1094
+ function useXAccount(chainIdentifier) {
1095
+ const resolvedChainType = chainIdentifier ? isChainType(chainIdentifier) ? chainIdentifier : getXChainType(chainIdentifier) : void 0;
1096
+ const xConnection = useXConnection(resolvedChainType);
1097
+ const xAccount = useMemo(() => {
1098
+ if (!resolvedChainType) {
1099
+ return {
1100
+ address: void 0,
1101
+ xChainType: void 0
1102
+ };
1103
+ }
1104
+ return xConnection?.xAccount || { address: void 0, xChainType: resolvedChainType };
1105
+ }, [resolvedChainType, xConnection]);
1106
+ return xAccount;
1107
+ }
1108
+ function useXAccounts() {
1109
+ const xChainTypes = useXWagmiStore((state) => Object.keys(state.xServices));
1110
+ const xConnections = useXWagmiStore((state) => state.xConnections);
1111
+ const { address: evmAddress } = useAccount();
1112
+ const suiAccount = useCurrentAccount();
1113
+ const solanaWallet = useWallet();
1114
+ const xAccounts = useMemo(() => {
1115
+ const result = {};
1116
+ for (const xChainType of xChainTypes) {
1117
+ const xConnection = xConnections[xChainType];
1118
+ if (xConnection?.xAccount) {
1119
+ result[xChainType] = xConnection.xAccount;
1120
+ } else {
1121
+ result[xChainType] = {
1122
+ address: void 0,
1123
+ xChainType
1124
+ };
1125
+ }
1126
+ }
1127
+ if (evmAddress) {
1128
+ result["EVM"] = {
1129
+ address: evmAddress,
1130
+ xChainType: "EVM"
1131
+ };
1132
+ }
1133
+ if (suiAccount) {
1134
+ result["SUI"] = {
1135
+ address: suiAccount.address,
1136
+ xChainType: "SUI"
1137
+ };
1138
+ }
1139
+ if (solanaWallet.publicKey) {
1140
+ result["SOLANA"] = {
1141
+ address: solanaWallet.publicKey.toString(),
1142
+ xChainType: "SOLANA"
1143
+ };
1144
+ }
1145
+ return result;
1146
+ }, [xChainTypes, xConnections, evmAddress, suiAccount, solanaWallet]);
1147
+ return xAccounts;
1148
+ }
1149
+ function useXConnect() {
1150
+ const setXConnection = useXWagmiStore((state) => state.setXConnection);
1151
+ const { connectAsync: evmConnectAsync } = useConnect();
1152
+ const { mutateAsync: suiConnectAsync } = useConnectWallet();
1153
+ const { select, connect, connected } = useWallet();
1154
+ return useMutation({
1155
+ mutationFn: async (xConnector) => {
1156
+ const xChainType = xConnector.xChainType;
1157
+ let xAccount;
1158
+ switch (xChainType) {
1159
+ case "EVM":
1160
+ await evmConnectAsync({ connector: xConnector.connector });
1161
+ break;
1162
+ case "SUI":
1163
+ await suiConnectAsync({ wallet: xConnector.wallet });
1164
+ break;
1165
+ case "SOLANA": {
1166
+ const walletName = xConnector.wallet.adapter.name;
1167
+ await select(walletName);
1168
+ const adapter = xConnector.wallet.adapter;
1169
+ if (!adapter) throw new Error("No adapter found for Solana wallet");
1170
+ if (walletName === "MetaMask") {
1171
+ await new Promise((resolve, reject) => {
1172
+ const timeout = setTimeout(() => {
1173
+ cleanup();
1174
+ reject(new Error("Wallet connection timeout"));
1175
+ }, 3e4);
1176
+ const handleConnect = () => {
1177
+ cleanup();
1178
+ resolve();
1179
+ };
1180
+ const handleError = (error) => {
1181
+ cleanup();
1182
+ reject(error);
1183
+ };
1184
+ const cleanup = () => {
1185
+ clearTimeout(timeout);
1186
+ adapter.off("connect", handleConnect);
1187
+ adapter.off("error", handleError);
1188
+ };
1189
+ adapter.on("connect", handleConnect);
1190
+ adapter.on("error", handleError);
1191
+ connect().catch((err) => {
1192
+ cleanup();
1193
+ reject(err);
1194
+ });
1195
+ });
1196
+ }
1197
+ break;
1198
+ }
1199
+ default:
1200
+ xAccount = await xConnector.connect();
1201
+ break;
1202
+ }
1203
+ if (xAccount) {
1204
+ setXConnection(xConnector.xChainType, {
1205
+ xAccount,
1206
+ xConnectorId: xConnector.id
1207
+ });
1208
+ }
1209
+ return xAccount;
1210
+ }
1211
+ });
1212
+ }
1213
+ var useStellarXConnectors = () => {
1214
+ const xService = useXService("STELLAR");
1215
+ return useQuery({
1216
+ queryKey: ["stellar-wallets", xService],
1217
+ queryFn: async () => {
1218
+ if (!xService) {
1219
+ return [];
1220
+ }
1221
+ const wallets = await xService.walletsKit.getSupportedWallets();
1222
+ return wallets.filter((wallet) => wallet.isAvailable).map((wallet) => new StellarWalletsKitXConnector(wallet));
1223
+ }
1224
+ });
1225
+ };
1226
+
1227
+ // src/hooks/useXService.ts
1228
+ function useXService(xChainType) {
1229
+ const xService = useXWagmiStore((state) => xChainType ? state.xServices[xChainType] : void 0);
1230
+ return xService;
1231
+ }
1232
+
1233
+ // src/hooks/useXConnectors.ts
1234
+ function useXConnectors(xChainType) {
1235
+ const xService = useXService(xChainType);
1236
+ const evmConnectors = useConnectors();
1237
+ const suiWallets = useWallets();
1238
+ const { data: stellarXConnectors } = useStellarXConnectors();
1239
+ const { wallets: solanaWallets } = useWallet();
1240
+ const xConnectors = useMemo(() => {
1241
+ if (!xChainType || !xService) {
1242
+ return [];
1243
+ }
1244
+ switch (xChainType) {
1245
+ case "EVM":
1246
+ return evmConnectors.map((connector) => new EvmXConnector(connector));
1247
+ case "SUI":
1248
+ return suiWallets.map((wallet) => new SuiXConnector(wallet));
1249
+ case "STELLAR":
1250
+ return stellarXConnectors || [];
1251
+ case "SOLANA":
1252
+ return solanaWallets.filter((wallet) => wallet.readyState === "Installed").map((wallet) => new SolanaXConnector(wallet));
1253
+ default:
1254
+ return xService.getXConnectors();
1255
+ }
1256
+ }, [xService, xChainType, evmConnectors, suiWallets, stellarXConnectors, solanaWallets]);
1257
+ return xConnectors;
1258
+ }
1259
+ function useXDisconnect() {
1260
+ const xConnections = useXWagmiStore((state) => state.xConnections);
1261
+ const unsetXConnection = useXWagmiStore((state) => state.unsetXConnection);
1262
+ const { disconnectAsync } = useDisconnect();
1263
+ const { mutateAsync: suiDisconnectAsync } = useDisconnectWallet();
1264
+ const solanaWallet = useWallet();
1265
+ return useCallback(
1266
+ async (xChainType) => {
1267
+ switch (xChainType) {
1268
+ case "EVM":
1269
+ await disconnectAsync();
1270
+ break;
1271
+ case "SUI":
1272
+ await suiDisconnectAsync();
1273
+ break;
1274
+ case "SOLANA":
1275
+ await solanaWallet.disconnect();
1276
+ break;
1277
+ default: {
1278
+ const xService = getXService(xChainType);
1279
+ const xConnectorId = xConnections[xChainType]?.xConnectorId;
1280
+ const xConnector = xConnectorId ? xService.getXConnectorById(xConnectorId) : void 0;
1281
+ await xConnector?.disconnect();
1282
+ break;
1283
+ }
1284
+ }
1285
+ unsetXConnection(xChainType);
1286
+ },
1287
+ [xConnections, unsetXConnection, disconnectAsync, suiDisconnectAsync, solanaWallet]
1288
+ );
1289
+ }
1290
+ function useXBalances({
1291
+ xChainId,
1292
+ xTokens,
1293
+ address
1294
+ }) {
1295
+ const xService = useXService(getXChainType(xChainId));
1296
+ return useQuery({
1297
+ queryKey: ["xBalances", xChainId, xTokens.map((x) => x.symbol), address],
1298
+ queryFn: async () => {
1299
+ if (!xService) {
1300
+ return {};
1301
+ }
1302
+ const balances = await xService.getBalances(address, xTokens, xChainId);
1303
+ return balances;
1304
+ },
1305
+ enabled: !!xService,
1306
+ placeholderData: keepPreviousData,
1307
+ refetchInterval: 5e3
1308
+ });
1309
+ }
1310
+ function useWalletProviderOptions(xChainId) {
1311
+ const xChainType = getXChainType(xChainId);
1312
+ const evmPublicClient = usePublicClient({
1313
+ chainId: xChainId ? getWagmiChainId(xChainId) : void 0
1314
+ });
1315
+ const { data: evmWalletClient } = useWalletClient({
1316
+ chainId: xChainId ? getWagmiChainId(xChainId) : void 0
1317
+ });
1318
+ const xService = useXService(getXChainType(xChainId));
1319
+ const xAccount = useXAccount(xChainId);
1320
+ return useMemo(() => {
1321
+ switch (xChainType) {
1322
+ case "EVM": {
1323
+ return { walletClient: evmWalletClient, publicClient: evmPublicClient };
1324
+ }
1325
+ case "SUI": {
1326
+ const suiXService = xService;
1327
+ return { client: suiXService.suiClient, wallet: suiXService.suiWallet, account: suiXService.suiAccount };
1328
+ }
1329
+ case "ICON": {
1330
+ return { walletAddress: xAccount.address, rpcUrl: CHAIN_INFO[1 /* MAINNET */].APIEndpoint };
1331
+ }
1332
+ case "INJECTIVE": {
1333
+ const injectiveXService = xService;
1334
+ const endpoints = getNetworkEndpoints(Network.Mainnet);
1335
+ return {
1336
+ walletAddress: xAccount.address,
1337
+ msgBroadcaster: injectiveXService.msgBroadcaster,
1338
+ rpcUrl: endpoints.rpc
1339
+ };
1340
+ }
1341
+ default:
1342
+ return void 0;
1343
+ }
1344
+ }, [xChainType, evmPublicClient, evmWalletClient, xService, xAccount]);
1345
+ }
1346
+ function useEthereumChainId() {
1347
+ const injectiveXService = useXService("INJECTIVE");
1348
+ const [ethereumChainId, setEthereumChainId] = React3.useState(null);
1349
+ useEffect(() => {
1350
+ if (!injectiveXService?.walletStrategy?.getWallet()) return;
1351
+ const walletStrategy = injectiveXService.walletStrategy;
1352
+ if (walletStrategy.getWallet() !== Wallet.Metamask) return;
1353
+ const getEthereumChainId = async () => {
1354
+ const chainId = await walletStrategy.getEthereumChainId();
1355
+ setEthereumChainId(Number.parseInt(chainId));
1356
+ };
1357
+ getEthereumChainId();
1358
+ walletStrategy.getStrategy().onChainIdChanged(getEthereumChainId);
1359
+ }, [injectiveXService?.walletStrategy]);
1360
+ return ethereumChainId;
1361
+ }
1362
+ var switchEthereumChain2 = async () => {
1363
+ const metamaskProvider = window.ethereum;
1364
+ return await Promise.race([
1365
+ metamaskProvider.request({
1366
+ method: "wallet_switchEthereumChain",
1367
+ params: [{ chainId: "0x1" }]
1368
+ }),
1369
+ new Promise(
1370
+ (resolve) => metamaskProvider.on("change", ({ chain }) => {
1371
+ if (chain?.id === 1) {
1372
+ resolve();
1373
+ }
1374
+ })
1375
+ )
1376
+ ]);
1377
+ };
1378
+ var useEvmSwitchChain = (expectedXChainId) => {
1379
+ const xChainType = getXChainType(expectedXChainId);
1380
+ const expectedChainId = xChainMap[expectedXChainId].id;
1381
+ const injectiveXService = useXService("INJECTIVE");
1382
+ const ethereumChainId = useEthereumChainId();
1383
+ const { chainId } = useAccount();
1384
+ const isWrongChain = useMemo(() => {
1385
+ return xChainType === "EVM" && chainId !== expectedChainId || xChainType === "INJECTIVE" && injectiveXService && injectiveXService.walletStrategy.getWallet() === Wallet.Metamask && ethereumChainId !== mainnet$1.id;
1386
+ }, [xChainType, chainId, expectedChainId, ethereumChainId, injectiveXService]);
1387
+ const { switchChain } = useSwitchChain();
1388
+ const handleSwitchChain = useCallback(() => {
1389
+ if (xChainType === "INJECTIVE") {
1390
+ switchEthereumChain2();
1391
+ } else {
1392
+ switchChain({ chainId: expectedChainId });
1393
+ }
1394
+ }, [switchChain, expectedChainId, xChainType]);
1395
+ return useMemo(
1396
+ () => ({
1397
+ isWrongChain,
1398
+ handleSwitchChain
1399
+ }),
1400
+ [isWrongChain, handleSwitchChain]
1401
+ );
1402
+ };
1403
+ function useWalletProvider(spokeChainId) {
1404
+ const xChainType = getXChainType(spokeChainId);
1405
+ const evmPublicClient = usePublicClient({
1406
+ chainId: spokeChainId ? getWagmiChainId(spokeChainId) : void 0
1407
+ });
1408
+ const { data: evmWalletClient } = useWalletClient({
1409
+ chainId: spokeChainId ? getWagmiChainId(spokeChainId) : void 0
1410
+ });
1411
+ const xService = useXService(getXChainType(spokeChainId));
1412
+ const xAccount = useXAccount(spokeChainId);
1413
+ return useMemo(() => {
1414
+ switch (xChainType) {
1415
+ case "EVM": {
1416
+ if (!evmWalletClient) {
1417
+ return void 0;
1418
+ }
1419
+ if (!evmPublicClient) {
1420
+ return void 0;
1421
+ }
1422
+ return new EvmWalletProvider({
1423
+ walletClient: evmWalletClient,
1424
+ publicClient: evmPublicClient
1425
+ });
1426
+ }
1427
+ case "SUI": {
1428
+ const suiXService = xService;
1429
+ const { client, wallet, account } = {
1430
+ client: suiXService.suiClient,
1431
+ wallet: suiXService.suiWallet,
1432
+ account: suiXService.suiAccount
1433
+ };
1434
+ return new SuiWalletProvider({ client, wallet, account });
1435
+ }
1436
+ case "ICON": {
1437
+ const { walletAddress, rpcUrl } = {
1438
+ walletAddress: xAccount.address,
1439
+ rpcUrl: CHAIN_INFO[1 /* MAINNET */].APIEndpoint
1440
+ };
1441
+ return new IconWalletProvider({
1442
+ walletAddress,
1443
+ rpcUrl
1444
+ });
1445
+ }
1446
+ case "INJECTIVE": {
1447
+ const injectiveXService = xService;
1448
+ if (!injectiveXService) {
1449
+ return void 0;
1450
+ }
1451
+ const { walletAddress, msgBroadcaster } = {
1452
+ walletAddress: xAccount.address,
1453
+ msgBroadcaster: injectiveXService.msgBroadcaster
1454
+ };
1455
+ return new InjectiveWalletProvider({
1456
+ walletAddress,
1457
+ msgBroadcaster
1458
+ });
1459
+ }
1460
+ case "STELLAR": {
1461
+ const stellarXService = xService;
1462
+ return new StellarWalletProvider({
1463
+ type: "BROWSER_EXTENSION",
1464
+ walletsKit: stellarXService.walletsKit,
1465
+ network: "PUBLIC"
1466
+ });
1467
+ }
1468
+ case "SOLANA": {
1469
+ const solanaXService = xService;
1470
+ if (!solanaXService.wallet) {
1471
+ throw new Error("Wallet is not initialized");
1472
+ }
1473
+ if (!solanaXService.connection) {
1474
+ throw new Error("Connection is not initialized");
1475
+ }
1476
+ return new SolanaWalletProvider({
1477
+ wallet: solanaXService.wallet,
1478
+ connection: solanaXService.connection
1479
+ });
1480
+ }
1481
+ default:
1482
+ return void 0;
1483
+ }
1484
+ }, [xChainType, evmPublicClient, evmWalletClient, xService, xAccount]);
1485
+ }
1486
+ var SodaxWalletProvider = ({ children, config }) => {
1487
+ useEffect(() => {
1488
+ initXWagmiStore(config);
1489
+ }, [config]);
1490
+ const {
1491
+ EVM: { chains },
1492
+ SOLANA: { endpoint }
1493
+ } = config;
1494
+ const wallets = useMemo(() => [new UnsafeBurnerWalletAdapter()], []);
1495
+ const wagmiConfig = useMemo(() => {
1496
+ return getWagmiConfig(chains);
1497
+ }, [chains]);
1498
+ return /* @__PURE__ */ React3.createElement(WagmiProvider, { config: wagmiConfig }, /* @__PURE__ */ React3.createElement(SuiClientProvider, { networks: { mainnet: { url: getFullnodeUrl("mainnet") } }, defaultNetwork: "mainnet" }, /* @__PURE__ */ React3.createElement(WalletProvider, { autoConnect: true }, /* @__PURE__ */ React3.createElement(ConnectionProvider, { endpoint }, /* @__PURE__ */ React3.createElement(WalletProvider$1, { wallets, autoConnect: true }, /* @__PURE__ */ React3.createElement(InitXWagmiStore, null), children)))));
1499
+ };
1500
+
1501
+ // src/types/index.ts
1502
+ var WalletId = /* @__PURE__ */ ((WalletId2) => {
1503
+ WalletId2["METAMASK"] = "metamask";
1504
+ WalletId2["HANA"] = "hana";
1505
+ WalletId2["PHANTOM"] = "phantom";
1506
+ WalletId2["SUI"] = "sui";
1507
+ WalletId2["KEPLR"] = "keplr";
1508
+ return WalletId2;
1509
+ })(WalletId || {});
1510
+
1511
+ export { EvmXConnector, EvmXService, IconHanaXConnector, IconXService, InitXWagmiStore, InjectiveKelprXConnector, InjectiveMetamaskXConnector, InjectiveXService, SodaxWalletProvider, SolanaXConnector, SolanaXService, StellarWalletsKitXConnector, StellarXService, SuiXConnector, SuiXService, WalletId, XConnector, XService, arbitrum, avalanche, base, bsc, getWagmiChainId, getXChainType, getXService, hyper, icon, initXWagmiStore, injective, isNativeToken, lightlink, nibiru, optimism, polygon, solana, sonic, stellar, sui, switchEthereumChain, useEvmSwitchChain, useWalletProvider, useWalletProviderOptions, useXAccount, useXAccounts, useXBalances, useXConnect, useXConnection, useXConnectors, useXDisconnect, useXService, useXWagmiStore, xChainMap, xChains };
1512
+ //# sourceMappingURL=index.mjs.map
1513
+ //# sourceMappingURL=index.mjs.map