@sodax/wallet-sdk-react 1.5.7-beta → 2.0.0-rc.1

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 (211) hide show
  1. package/README.md +103 -145
  2. package/ai-exported/AGENTS.md +122 -0
  3. package/ai-exported/integration/README.md +102 -0
  4. package/ai-exported/integration/ai-rules.md +136 -0
  5. package/ai-exported/integration/architecture.md +181 -0
  6. package/ai-exported/integration/examples/01-minimal-evm.tsx +75 -0
  7. package/ai-exported/integration/examples/02-multi-chain-modal.tsx +169 -0
  8. package/ai-exported/integration/examples/03-nextjs-app-router.tsx +99 -0
  9. package/ai-exported/integration/examples/04-walletconnect-setup.tsx +89 -0
  10. package/ai-exported/integration/examples/README.md +29 -0
  11. package/ai-exported/integration/recipes/batch-operations.md +223 -0
  12. package/ai-exported/integration/recipes/bridge-to-sdk.md +164 -0
  13. package/ai-exported/integration/recipes/chain-detection.md +254 -0
  14. package/ai-exported/integration/recipes/connect-button.md +156 -0
  15. package/ai-exported/integration/recipes/multi-chain-modal.md +199 -0
  16. package/ai-exported/integration/recipes/setup.md +158 -0
  17. package/ai-exported/integration/recipes/sign-message.md +137 -0
  18. package/ai-exported/integration/recipes/sub-path-imports.md +95 -0
  19. package/ai-exported/integration/recipes/switch-chain.md +141 -0
  20. package/ai-exported/integration/recipes/walletconnect-setup.md +139 -0
  21. package/ai-exported/integration/reference/api-surface.md +175 -0
  22. package/ai-exported/integration/reference/chain-support.md +78 -0
  23. package/ai-exported/integration/reference/connectors.md +74 -0
  24. package/ai-exported/integration/reference/hooks.md +204 -0
  25. package/ai-exported/integration/reference/wallet-brands.md +106 -0
  26. package/ai-exported/migration/README.md +49 -0
  27. package/ai-exported/migration/ai-rules.md +144 -0
  28. package/ai-exported/migration/breaking-changes.md +305 -0
  29. package/ai-exported/migration/checklist.md +159 -0
  30. package/ai-exported/migration/recipes/connect-button.md +166 -0
  31. package/ai-exported/migration/recipes/multi-chain-modal.md +244 -0
  32. package/ai-exported/migration/recipes/ssr-setup.md +162 -0
  33. package/ai-exported/migration/recipes/walletconnect-migration.md +168 -0
  34. package/ai-exported/migration/reference/components.md +73 -0
  35. package/ai-exported/migration/reference/config.md +307 -0
  36. package/ai-exported/migration/reference/hooks.md +278 -0
  37. package/ai-exported/migration/reference/imports.md +157 -0
  38. package/dist/XConnector-B9YQTVJ4.d.ts +146 -0
  39. package/dist/chunk-2BOUGCJ7.mjs +150 -0
  40. package/dist/chunk-2BOUGCJ7.mjs.map +1 -0
  41. package/dist/chunk-66BAUK56.mjs +202 -0
  42. package/dist/chunk-66BAUK56.mjs.map +1 -0
  43. package/dist/chunk-7ULB6DW4.mjs +102 -0
  44. package/dist/chunk-7ULB6DW4.mjs.map +1 -0
  45. package/dist/chunk-BKJB527E.mjs +125 -0
  46. package/dist/chunk-BKJB527E.mjs.map +1 -0
  47. package/dist/chunk-BXJLBR4G.mjs +88 -0
  48. package/dist/chunk-BXJLBR4G.mjs.map +1 -0
  49. package/dist/chunk-E5IAZ7E6.mjs +186 -0
  50. package/dist/chunk-E5IAZ7E6.mjs.map +1 -0
  51. package/dist/chunk-MAQ47Q52.mjs +33 -0
  52. package/dist/chunk-MAQ47Q52.mjs.map +1 -0
  53. package/dist/chunk-MXZVF5HR.mjs +34 -0
  54. package/dist/chunk-MXZVF5HR.mjs.map +1 -0
  55. package/dist/chunk-N5A2TMF6.mjs +33 -0
  56. package/dist/chunk-N5A2TMF6.mjs.map +1 -0
  57. package/dist/chunk-NY7U7OJW.mjs +64 -0
  58. package/dist/chunk-NY7U7OJW.mjs.map +1 -0
  59. package/dist/chunk-PJLEJVAU.mjs +140 -0
  60. package/dist/chunk-PJLEJVAU.mjs.map +1 -0
  61. package/dist/chunk-PLCA4ZDJ.mjs +1585 -0
  62. package/dist/chunk-PLCA4ZDJ.mjs.map +1 -0
  63. package/dist/chunk-TZMKDXFA.mjs +3 -0
  64. package/dist/chunk-TZMKDXFA.mjs.map +1 -0
  65. package/dist/chunk-X2MHIWXO.mjs +100 -0
  66. package/dist/chunk-X2MHIWXO.mjs.map +1 -0
  67. package/dist/chunk-XZ7CHO2S.mjs +41 -0
  68. package/dist/chunk-XZ7CHO2S.mjs.map +1 -0
  69. package/dist/config-OlnzyEUE.d.ts +146 -0
  70. package/dist/index.cjs +2784 -1594
  71. package/dist/index.cjs.map +1 -1
  72. package/dist/index.d.ts +768 -1498
  73. package/dist/index.mjs +463 -2004
  74. package/dist/index.mjs.map +1 -1
  75. package/dist/xchains/bitcoin/index.cjs +1927 -0
  76. package/dist/xchains/bitcoin/index.cjs.map +1 -0
  77. package/dist/xchains/bitcoin/index.d.ts +125 -0
  78. package/dist/xchains/bitcoin/index.mjs +16 -0
  79. package/dist/xchains/bitcoin/index.mjs.map +1 -0
  80. package/dist/xchains/evm/index.cjs +316 -0
  81. package/dist/xchains/evm/index.cjs.map +1 -0
  82. package/dist/xchains/evm/index.d.ts +39 -0
  83. package/dist/xchains/evm/index.mjs +5 -0
  84. package/dist/xchains/evm/index.mjs.map +1 -0
  85. package/dist/xchains/icon/index.cjs +311 -0
  86. package/dist/xchains/icon/index.cjs.map +1 -0
  87. package/dist/xchains/icon/index.d.ts +37 -0
  88. package/dist/xchains/icon/index.mjs +7 -0
  89. package/dist/xchains/icon/index.mjs.map +1 -0
  90. package/dist/xchains/injective/index.cjs +223 -0
  91. package/dist/xchains/injective/index.cjs.map +1 -0
  92. package/dist/xchains/injective/index.d.ts +35 -0
  93. package/dist/xchains/injective/index.mjs +5 -0
  94. package/dist/xchains/injective/index.mjs.map +1 -0
  95. package/dist/xchains/near/index.cjs +190 -0
  96. package/dist/xchains/near/index.cjs.map +1 -0
  97. package/dist/xchains/near/index.d.ts +34 -0
  98. package/dist/xchains/near/index.mjs +6 -0
  99. package/dist/xchains/near/index.mjs.map +1 -0
  100. package/dist/xchains/solana/index.cjs +186 -0
  101. package/dist/xchains/solana/index.cjs.map +1 -0
  102. package/dist/xchains/solana/index.d.ts +26 -0
  103. package/dist/xchains/solana/index.mjs +7 -0
  104. package/dist/xchains/solana/index.mjs.map +1 -0
  105. package/dist/xchains/stacks/index.cjs +240 -0
  106. package/dist/xchains/stacks/index.cjs.map +1 -0
  107. package/dist/xchains/stacks/index.d.ts +36 -0
  108. package/dist/xchains/stacks/index.mjs +5 -0
  109. package/dist/xchains/stacks/index.mjs.map +1 -0
  110. package/dist/xchains/stellar/index.cjs +322 -0
  111. package/dist/xchains/stellar/index.cjs.map +1 -0
  112. package/dist/xchains/stellar/index.d.ts +44 -0
  113. package/dist/xchains/stellar/index.mjs +6 -0
  114. package/dist/xchains/stellar/index.mjs.map +1 -0
  115. package/dist/xchains/sui/index.cjs +248 -0
  116. package/dist/xchains/sui/index.cjs.map +1 -0
  117. package/dist/xchains/sui/index.d.ts +37 -0
  118. package/dist/xchains/sui/index.mjs +7 -0
  119. package/dist/xchains/sui/index.mjs.map +1 -0
  120. package/docs/ADDING_A_NEW_CHAIN.md +440 -0
  121. package/docs/ARCHITECTURE.md +291 -0
  122. package/docs/BATCH_OPERATIONS.md +267 -0
  123. package/docs/CHAIN_DETECTION.md +216 -0
  124. package/docs/CONFIGURE_PROVIDER.md +360 -0
  125. package/docs/CONNECTORS.md +247 -0
  126. package/docs/CONNECT_FLOW.md +276 -0
  127. package/docs/EVM_SWITCH_CHAIN.md +161 -0
  128. package/docs/SIGN_MESSAGE.md +213 -0
  129. package/docs/SUB_PATH_EXPORTS.md +246 -0
  130. package/docs/WALLETCONNECT.md +154 -0
  131. package/docs/WALLET_MODAL.md +331 -0
  132. package/docs/WALLET_PROVIDER_BRIDGE.md +226 -0
  133. package/package.json +34 -9
  134. package/skills/SKILLS.md +84 -0
  135. package/skills/bridge-to-sdk.md +148 -0
  136. package/skills/connect-button.md +116 -0
  137. package/skills/evm-only-walletconnect.md +111 -0
  138. package/skills/multi-chain-modal.md +178 -0
  139. package/skills/setup.md +107 -0
  140. package/dist/index.d.cts +0 -1579
  141. package/src/Hydrate.ts +0 -65
  142. package/src/SodaxWalletProvider.tsx +0 -97
  143. package/src/actions/getXChainType.ts +0 -8
  144. package/src/actions/getXService.ts +0 -33
  145. package/src/actions/index.ts +0 -2
  146. package/src/assets/wallets/hana.svg +0 -6
  147. package/src/assets/wallets/havah.svg +0 -76
  148. package/src/assets/wallets/keplr.svg +0 -30
  149. package/src/assets/wallets/metamask.svg +0 -60
  150. package/src/assets/wallets/phantom.svg +0 -4
  151. package/src/assets/wallets/sui.svg +0 -20
  152. package/src/core/XConnector.ts +0 -54
  153. package/src/core/XService.ts +0 -85
  154. package/src/core/index.ts +0 -2
  155. package/src/hooks/index.ts +0 -11
  156. package/src/hooks/useEthereumChainId.ts +0 -44
  157. package/src/hooks/useEvmSwitchChain.ts +0 -91
  158. package/src/hooks/useWalletProvider.ts +0 -206
  159. package/src/hooks/useXAccount.ts +0 -51
  160. package/src/hooks/useXAccounts.ts +0 -56
  161. package/src/hooks/useXBalances.ts +0 -65
  162. package/src/hooks/useXConnect.ts +0 -118
  163. package/src/hooks/useXConnection.ts +0 -72
  164. package/src/hooks/useXConnectors.ts +0 -72
  165. package/src/hooks/useXDisconnect.ts +0 -73
  166. package/src/hooks/useXService.ts +0 -8
  167. package/src/hooks/useXSignMessage.ts +0 -82
  168. package/src/index.ts +0 -19
  169. package/src/types/index.ts +0 -22
  170. package/src/useXWagmiStore.ts +0 -116
  171. package/src/utils/index.ts +0 -21
  172. package/src/xchains/bitcoin/BitcoinXConnector.ts +0 -34
  173. package/src/xchains/bitcoin/BitcoinXService.ts +0 -40
  174. package/src/xchains/bitcoin/OKXXConnector.ts +0 -117
  175. package/src/xchains/bitcoin/UnisatXConnector.ts +0 -117
  176. package/src/xchains/bitcoin/XverseXConnector.ts +0 -232
  177. package/src/xchains/bitcoin/index.ts +0 -7
  178. package/src/xchains/bitcoin/useBitcoinXConnectors.ts +0 -14
  179. package/src/xchains/evm/EvmXConnector.ts +0 -27
  180. package/src/xchains/evm/EvmXService.ts +0 -211
  181. package/src/xchains/evm/index.ts +0 -3
  182. package/src/xchains/icon/IconHanaXConnector.ts +0 -39
  183. package/src/xchains/icon/IconXService.ts +0 -117
  184. package/src/xchains/icon/actions.ts +0 -28
  185. package/src/xchains/icon/iconex/index.tsx +0 -46
  186. package/src/xchains/icon/index.ts +0 -2
  187. package/src/xchains/injective/InjectiveXConnector.ts +0 -60
  188. package/src/xchains/injective/InjectiveXService.ts +0 -62
  189. package/src/xchains/injective/actions.ts +0 -32
  190. package/src/xchains/injective/index.ts +0 -2
  191. package/src/xchains/near/NearXConnector.ts +0 -42
  192. package/src/xchains/near/NearXService.ts +0 -46
  193. package/src/xchains/near/useNearXConnectors.ts +0 -23
  194. package/src/xchains/solana/SolanaXConnector.ts +0 -26
  195. package/src/xchains/solana/SolanaXService.ts +0 -46
  196. package/src/xchains/solana/index.ts +0 -2
  197. package/src/xchains/stacks/StacksXConnector.ts +0 -63
  198. package/src/xchains/stacks/StacksXService.ts +0 -59
  199. package/src/xchains/stacks/constants.ts +0 -42
  200. package/src/xchains/stacks/index.ts +0 -4
  201. package/src/xchains/stacks/useStacksXConnectors.ts +0 -7
  202. package/src/xchains/stellar/CustomSorobanServer.ts +0 -93
  203. package/src/xchains/stellar/StellarWalletsKitXConnector.ts +0 -53
  204. package/src/xchains/stellar/StellarXService.ts +0 -93
  205. package/src/xchains/stellar/actions.ts +0 -24
  206. package/src/xchains/stellar/index.tsx +0 -2
  207. package/src/xchains/stellar/useStellarXConnectors.ts +0 -21
  208. package/src/xchains/stellar/utils.ts +0 -49
  209. package/src/xchains/sui/SuiXConnector.ts +0 -28
  210. package/src/xchains/sui/SuiXService.ts +0 -66
  211. package/src/xchains/sui/index.ts +0 -2
package/dist/index.mjs CHANGED
@@ -1,2079 +1,538 @@
1
- import { detectBitcoinAddressType, baseChainInfo, KAIA_MAINNET_CHAIN_ID, REDBELLY_MAINNET_CHAIN_ID, LIGHTLINK_MAINNET_CHAIN_ID, HYPEREVM_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, ETHEREUM_MAINNET_CHAIN_ID, ChainTypeArr } from '@sodax/types';
2
- import { NearConnector } from '@hot-labs/near-connect';
3
- import { JsonRpcProvider } from 'near-api-js';
4
- import { fetchCallReadOnlyFunction, Cl } from '@stacks/transactions';
5
- import { networkFrom, createNetwork } from '@stacks/network';
6
- import { AddressPurpose, MessageSigningProtocols } from 'sats-connect';
7
- import React2, { useMemo, useCallback, useEffect } from 'react';
8
- import { useCurrentAccount, useCurrentWallet, useConnectWallet, useWallets, useDisconnectWallet, useSignPersonalMessage, SuiClientProvider, WalletProvider, useSuiClient } from '@mysten/dapp-kit';
9
- import { useWallet, ConnectionProvider, WalletProvider as WalletProvider$1, useConnection } from '@solana/wallet-adapter-react';
10
- import { createConfig, createStorage, http, cookieStorage, useConnections, useAccount, useConnect, useConnectors, useDisconnect, useSwitchChain, usePublicClient, useWalletClient, useSignMessage, WagmiProvider, useConfig } from 'wagmi';
11
- import { create } from 'zustand';
12
- import { devtools, persist, createJSONStorage } from 'zustand/middleware';
13
- import { immer } from 'zustand/middleware/immer';
14
- import { erc20Abi, defineChain } from 'viem';
15
- import { getPublicClient } from 'wagmi/actions';
16
- import { mainnet, avalanche, arbitrum, base, bsc, sonic, optimism, polygon, lightlinkPhoenix, kaia, redbellyMainnet } from 'wagmi/chains';
17
- import { getNetworkEndpoints, Network } from '@injectivelabs/networks';
18
- import { getInjectiveAddress, IndexerGrpcAccountPortfolioApi, ChainGrpcWasmApi, getEthereumAddress } from '@injectivelabs/sdk-ts';
19
- import { ChainId } from '@injectivelabs/ts-types';
20
- import { MsgBroadcaster } from '@injectivelabs/wallet-core';
21
- import { WalletStrategy } from '@injectivelabs/wallet-strategy';
22
- import { Wallet, isEvmBrowserWallet, isCosmosBrowserWallet } from '@injectivelabs/wallet-base';
23
- import { isCosmosWalletInstalled } from '@injectivelabs/wallet-cosmos';
24
- import { PublicKey } from '@solana/web3.js';
25
- import { getAssociatedTokenAddressSync, getAccount } from '@solana/spl-token';
26
- import { StellarWalletsKit, allowAllModules, WalletNetwork } from '@creit.tech/stellar-wallets-kit';
27
- import * as StellarSdk from '@stellar/stellar-sdk';
28
- import { SorobanRpc, Address, Contract, TimeoutInfinite, scValToBigInt, xdr } from '@stellar/stellar-sdk';
29
- import * as IconSdkRaw from 'icon-sdk-js';
30
- import { request as request$1, disconnect } from '@stacks/connect';
31
- import { QueryClient, useMutation, useQuery, QueryClientProvider } from '@tanstack/react-query';
32
- import { mainnet as mainnet$1 } from 'viem/chains';
33
- import { StacksWalletProvider, NearWalletProvider, SolanaWalletProvider, StellarWalletProvider, InjectiveWalletProvider, IconWalletProvider, SuiWalletProvider, EvmWalletProvider } from '@sodax/wallet-sdk-core';
1
+ import { WalletConfigProvider, useXWalletStore, chainRegistry, useWalletConfig } from './chunk-PLCA4ZDJ.mjs';
2
+ export { WalletConfigProvider, getXChainType, getXService, useBatchConnect, useBatchDisconnect, useChainGroups, useConnectedChains, useConnectionFlow, useEnabledChainTypes, useEnabledChains, useEvmSwitchChain, useIsChainEnabled, useIsWalletInstalled, useWalletConfig, useWalletModal, useWalletProvider, useXAccount, useXAccounts, useXConnect, useXConnection, useXConnections, useXConnectors, useXConnectorsByChain, useXDisconnect, useXService, useXServices, useXSignMessage } from './chunk-PLCA4ZDJ.mjs';
3
+ import { StellarXService } from './chunk-66BAUK56.mjs';
4
+ import { SuiXService, SuiXConnector } from './chunk-7ULB6DW4.mjs';
5
+ import { createWagmiConfig, EvmXService, EvmXConnector } from './chunk-E5IAZ7E6.mjs';
6
+ import { request } from './chunk-2BOUGCJ7.mjs';
7
+ import { assertSuiProviderShape } from './chunk-MAQ47Q52.mjs';
8
+ import { InjectiveXService } from './chunk-BKJB527E.mjs';
9
+ import './chunk-BXJLBR4G.mjs';
10
+ import { SOLANA_DEFAULT_AUTO_CONNECT, SOLANA_DEFAULT_RPC_URL, SUI_DEFAULT_AUTO_CONNECT, SUI_DEFAULT_NETWORK, EVM_DEFAULT_RECONNECT_ON_MOUNT, EVM_DEFAULT_SSR, SOLANA_METAMASK_CONNECT_TIMEOUT_MS } from './chunk-MXZVF5HR.mjs';
11
+ import { SolanaXConnector } from './chunk-N5A2TMF6.mjs';
12
+ import { SolanaXService } from './chunk-XZ7CHO2S.mjs';
13
+ import { getEntryDefaults, resolveEvmDefaults } from './chunk-NY7U7OJW.mjs';
14
+ export { getEntryDefaults, getRpcUrl, getWagmiChainId, isNativeToken, resolveEvmDefaults, sortConnectors } from './chunk-NY7U7OJW.mjs';
15
+ import './chunk-PJLEJVAU.mjs';
16
+ import './chunk-TZMKDXFA.mjs';
17
+ export { XConnector, XService } from './chunk-X2MHIWXO.mjs';
18
+ import { useRef, useEffect, useMemo, useState } from 'react';
19
+ import { WagmiProvider, useConfig, useConnectors, useAccount, usePublicClient, useWalletClient, useReconnect, useConnect, useDisconnect, useSignMessage } from 'wagmi';
20
+ import { walletConnect } from 'wagmi/connectors';
21
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
22
+ import { SolanaWalletProvider, SuiWalletProvider, EvmWalletProvider } from '@sodax/wallet-sdk-core';
23
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
24
+ import { ConnectionProvider, WalletProvider, useConnection, useWallet } from '@solana/wallet-adapter-react';
25
+ import { ChainKeys } from '@sodax/types';
26
+ import { SuiClientProvider, WalletProvider as WalletProvider$1, useSuiClient, useCurrentWallet, useCurrentAccount, useWallets, useConnectWallet, useDisconnectWallet, useSignPersonalMessage } from '@mysten/dapp-kit';
34
27
  import { getFullnodeUrl } from '@mysten/sui/client';
35
- import { UnsafeBurnerWalletAdapter } from '@solana/wallet-adapter-wallets';
28
+ import { isEvmBrowserWallet, Wallet } from '@injectivelabs/wallet-base';
29
+ import { getInjectiveAddress } from '@injectivelabs/sdk-ts';
36
30
 
37
- // src/actions/getXChainType.ts
38
- function getXChainType(xChainId) {
39
- if (!xChainId) {
40
- return void 0;
41
- }
42
- return baseChainInfo[xChainId].type;
43
- }
44
-
45
- // src/core/XService.ts
46
- var XService = class {
47
- constructor(xChainType) {
48
- /** Available wallet connectors for this chain */
49
- this.xConnectors = [];
50
- this.xChainType = xChainType;
51
- }
52
- /**
53
- * Gets the balance of a specific token for an address
54
- * @param address The wallet address to check
55
- * @param xToken The token to get the balance for
56
- * @returns Promise resolving to the token balance as a bigint
57
- */
58
- async getBalance(address, xToken) {
59
- return 0n;
60
- }
61
- /**
62
- * Gets balances for multiple tokens for an address
63
- * @param address The wallet address to check
64
- * @param xTokens Array of tokens to get balances for
65
- * @returns Promise resolving to object mapping token addresses to balances
66
- */
67
- async getBalances(address, xTokens) {
68
- if (!address) return {};
69
- const balancePromises = xTokens.map(async (xToken) => {
70
- const balance = await this.getBalance(address, xToken);
71
- return { address: xToken.address, balance };
72
- });
73
- const balances = await Promise.all(balancePromises);
74
- return balances.reduce((acc, { address: address2, balance }) => {
75
- acc[address2] = balance;
76
- return acc;
77
- }, {});
78
- }
79
- /**
80
- * Gets all available connectors for this chain
81
- */
82
- getXConnectors() {
83
- return this.xConnectors;
84
- }
85
- /**
86
- * Sets the available connectors for this chain
87
- */
88
- setXConnectors(xConnectors) {
89
- this.xConnectors = xConnectors;
90
- }
91
- /**
92
- * Gets a specific connector by its ID
93
- * @param xConnectorId The connector ID to look up
94
- * @returns The matching connector or undefined if not found
95
- */
96
- getXConnectorById(xConnectorId) {
97
- return this.getXConnectors().find((xConnector) => xConnector.id === xConnectorId);
98
- }
99
- };
100
- var NearXService = class _NearXService extends XService {
101
- constructor() {
102
- super("NEAR");
103
- this.walletSelector = new NearConnector({
104
- network: "mainnet",
105
- logger: console,
106
- autoConnect: true,
107
- excludedWallets: ["okx-wallet"]
108
- });
109
- }
110
- static getInstance() {
111
- if (!_NearXService.instance) {
112
- _NearXService.instance = new _NearXService();
113
- }
114
- return _NearXService.instance;
115
- }
116
- async getBalance(address, xToken) {
117
- const url = "https://1rpc.io/near";
118
- const provider = new JsonRpcProvider({ url });
119
- if (xToken.symbol === "NEAR") {
120
- const account = await provider.viewAccount({ accountId: address ?? "" });
121
- return BigInt(account.amount);
122
- }
123
- const res = await provider.callFunction({ contractId: xToken.address, method: "ft_balance_of", args: { account_id: address } });
124
- return BigInt(res ?? 0);
125
- }
126
- };
127
- var StacksXService = class _StacksXService extends XService {
128
- constructor() {
129
- super("STACKS");
130
- this.network = networkFrom("mainnet");
131
- }
132
- static getInstance() {
133
- if (!_StacksXService.instance) {
134
- _StacksXService.instance = new _StacksXService();
135
- }
136
- return _StacksXService.instance;
137
- }
138
- async getBalance(address, xToken) {
139
- if (!address) return 0n;
140
- if (xToken.symbol === "STX") {
141
- const url = `${this.network?.client.baseUrl}/extended/v1/address/${address}/balances`;
142
- try {
143
- const response = await fetch(url);
144
- if (!response.ok) {
145
- throw new Error(`Error fetching data: ${response.statusText}`);
146
- }
147
- const data = await response.json();
148
- return BigInt(data.stx.balance);
149
- } catch (error) {
150
- console.error("Error fetching STX balance:", error);
151
- return 0n;
152
- }
153
- }
154
- const [contractAddress, contractName] = xToken.address.split(".");
155
- try {
156
- const result = await fetchCallReadOnlyFunction({
157
- contractAddress,
158
- contractName,
159
- functionName: "get-balance",
160
- functionArgs: [Cl.principal(address)],
161
- network: this.network,
162
- senderAddress: address
163
- });
164
- return result.value.value;
165
- } catch (error) {
166
- console.error("Error fetching token balance:", error);
167
- return 0n;
168
- }
169
- }
170
- };
171
-
172
- // src/actions/getXService.ts
173
- function getXService(xChainType) {
174
- switch (xChainType) {
175
- case "BITCOIN":
176
- return BitcoinXService.getInstance();
177
- case "EVM":
178
- return EvmXService.getInstance();
179
- case "SUI":
180
- return SuiXService.getInstance();
181
- case "SOLANA":
182
- return SolanaXService.getInstance();
183
- case "ICON":
184
- return IconXService.getInstance();
185
- case "INJECTIVE":
186
- return InjectiveXService.getInstance();
187
- case "STELLAR":
188
- return StellarXService.getInstance();
189
- case "NEAR":
190
- return NearXService.getInstance();
191
- case "STACKS":
192
- return StacksXService.getInstance();
193
- default:
194
- throw new Error(`Unsupported chain type: ${xChainType}`);
195
- }
196
- }
197
-
198
- // src/core/XConnector.ts
199
- var XConnector = class {
200
- constructor(xChainType, name, id) {
201
- this.xChainType = xChainType;
202
- this.name = name;
203
- this._id = id;
204
- }
205
- /** Get the unique identifier for this connector */
206
- get id() {
207
- return this._id;
208
- }
209
- /** Get the optional icon URL for this wallet provider */
210
- get icon() {
211
- return this._icon;
212
- }
213
- };
214
- var isNativeToken = (xToken) => {
215
- const nativeAddresses = [
216
- "cx0000000000000000000000000000000000000000",
217
- "0x0000000000000000000000000000000000000000",
218
- "inj",
219
- "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI",
220
- "hx0000000000000000000000000000000000000000",
221
- "11111111111111111111111111111111",
222
- // solana
223
- "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA",
224
- // stellar
225
- "ST000000000000000000002AMW42H.nativetoken",
226
- // stacks
227
- "0:0"
228
- // bitcoin
229
- ];
230
- return nativeAddresses.includes(xToken.address);
231
- };
232
- var getWagmiChainId = (xChainId) => {
233
- return baseChainInfo[xChainId].chainId;
234
- };
235
-
236
- // src/xchains/bitcoin/BitcoinXService.ts
237
- var BitcoinXService = class _BitcoinXService extends XService {
238
- constructor(rpcUrl = "https://mempool.space/api") {
239
- super("BITCOIN");
240
- this.rpcUrl = rpcUrl;
241
- }
242
- static getInstance(rpcUrl) {
243
- if (!_BitcoinXService.instance) {
244
- _BitcoinXService.instance = new _BitcoinXService(rpcUrl);
245
- } else if (rpcUrl && rpcUrl !== _BitcoinXService.instance.rpcUrl) {
246
- _BitcoinXService.instance.rpcUrl = rpcUrl;
247
- }
248
- return _BitcoinXService.instance;
249
- }
250
- async getBalance(address, xToken) {
251
- if (!address) return 0n;
252
- try {
253
- if (isNativeToken(xToken)) {
254
- const response = await fetch(`${this.rpcUrl}/address/${address}/utxo`);
255
- if (!response.ok) return 0n;
256
- const utxos = await response.json();
257
- const totalBalance = utxos.reduce((sum, utxo) => sum + utxo.value, 0);
258
- return BigInt(totalBalance);
259
- }
260
- } catch {
261
- return 0n;
262
- }
263
- return 0n;
264
- }
265
- };
266
-
267
- // src/xchains/bitcoin/BitcoinXConnector.ts
268
- var BitcoinXConnector = class extends XConnector {
269
- constructor(name, id) {
270
- super("BITCOIN", name, id);
271
- }
272
- getXService() {
273
- return BitcoinXService.getInstance();
274
- }
275
- };
276
- var UnisatWalletProvider = class {
277
- constructor(unisat, address) {
278
- this.unisat = unisat;
279
- this.cachedAddress = address;
280
- }
281
- async getWalletAddress() {
282
- try {
283
- const accounts = await this.unisat.getAccounts();
284
- if (accounts[0]) this.cachedAddress = accounts[0];
285
- } catch {
286
- }
287
- return this.cachedAddress;
288
- }
289
- async getPublicKey() {
290
- return this.unisat.getPublicKey();
291
- }
292
- async getAddressType(_address) {
293
- const address = await this.getWalletAddress();
294
- return detectBitcoinAddressType(address);
295
- }
296
- async signTransaction(psbtBase64, finalize = false) {
297
- const psbtHex = Buffer.from(psbtBase64, "base64").toString("hex");
298
- const signedHex = await this.unisat.signPsbt(psbtHex, { autoFinalized: finalize });
299
- return signedHex;
300
- }
301
- async signEcdsaMessage(message) {
302
- return this.unisat.signMessage(message, "ecdsa");
303
- }
304
- async signBip322Message(message) {
305
- return this.unisat.signMessage(message, "bip322-simple");
306
- }
307
- async sendBitcoin(toAddress, satoshis) {
308
- if (satoshis > BigInt(Number.MAX_SAFE_INTEGER)) {
309
- throw new Error(`Amount ${satoshis} satoshis exceeds safe integer range`);
310
- }
311
- return this.unisat.sendBitcoin(toAddress, Number(satoshis));
312
- }
313
- };
314
- var UnisatXConnector = class extends BitcoinXConnector {
315
- constructor() {
316
- super("Unisat", "unisat");
317
- }
318
- static isAvailable() {
319
- return typeof window !== "undefined" && !!window.unisat;
320
- }
321
- get icon() {
322
- return "https://avatars.githubusercontent.com/u/125119198?s=200&v=4";
323
- }
324
- async connect() {
325
- if (!window.unisat) {
326
- throw new Error("Unisat wallet is not installed");
327
- }
328
- const accounts = await window.unisat.requestAccounts();
329
- const address = accounts[0];
330
- if (!address) return void 0;
331
- this.walletProvider = new UnisatWalletProvider(window.unisat, address);
332
- return {
333
- address,
334
- xChainType: "BITCOIN"
335
- };
336
- }
337
- async disconnect() {
338
- this.walletProvider = void 0;
339
- }
340
- getWalletProvider() {
341
- return this.walletProvider;
342
- }
343
- recreateWalletProvider(xAccount) {
344
- if (!window.unisat || !xAccount.address) return void 0;
345
- return new UnisatWalletProvider(window.unisat, xAccount.address);
346
- }
347
- };
348
- var XverseWalletProvider = class {
349
- constructor(address, publicKey) {
350
- this.address = address;
351
- this.publicKey = publicKey;
352
- }
353
- async getWalletAddress() {
354
- return this.address;
355
- }
356
- async getPublicKey() {
357
- return this.publicKey;
358
- }
359
- async getAddressType(_address) {
360
- return detectBitcoinAddressType(this.address);
361
- }
362
- /**
363
- * Parse a base64-encoded PSBT to count the number of inputs.
364
- * Reads the unsigned transaction from the PSBT global section.
365
- */
366
- countPsbtInputs(psbtBase64) {
367
- const data = Buffer.from(psbtBase64, "base64");
368
- let offset = 5;
369
- const keyLen = data[offset++] ?? 0;
370
- if (keyLen !== 1 || data[offset++] !== 0) {
371
- return 1;
372
- }
373
- const firstByte = data[offset++] ?? 0;
374
- if (firstByte === 253) offset += 2;
375
- else if (firstByte === 254) offset += 4;
376
- else if (firstByte === 255) offset += 8;
377
- offset += 4;
378
- const inputByte = data[offset] ?? 0;
379
- if (inputByte < 253) return inputByte;
380
- return 1;
381
- }
382
- async signTransaction(psbtBase64, finalize = false) {
383
- const { request: request3 } = await import('sats-connect');
384
- const inputCount = this.countPsbtInputs(psbtBase64);
385
- const signingIndexes = Array.from({ length: inputCount }, (_, i) => i);
386
- const response = await request3("signPsbt", {
387
- psbt: psbtBase64,
388
- broadcast: false,
389
- signInputs: {
390
- [this.address]: signingIndexes
391
- }
392
- });
393
- if (response.status === "error") {
394
- throw new Error(response.error?.message || "Xverse PSBT signing failed");
395
- }
396
- const result = response.result;
397
- if (finalize) {
398
- return Buffer.from(result.psbt, "base64").toString("hex");
399
- }
400
- return result.psbt;
401
- }
402
- async signEcdsaMessage(message) {
403
- const { request: request3 } = await import('sats-connect');
404
- const response = await request3("signMessage", {
405
- address: this.address,
406
- message,
407
- protocol: MessageSigningProtocols.ECDSA
408
- });
409
- if (response.status === "error") {
410
- throw new Error(response.error?.message || "Xverse ECDSA signing failed");
411
- }
412
- return response.result.signature;
413
- }
414
- async signBip322Message(message) {
415
- const { request: request3 } = await import('sats-connect');
416
- const response = await request3("signMessage", {
417
- address: this.address,
418
- message,
419
- protocol: MessageSigningProtocols.BIP322
420
- });
421
- if (response.status === "error") {
422
- throw new Error(response.error?.message || "Xverse BIP322 signing failed");
423
- }
424
- return response.result.signature;
425
- }
426
- async sendBitcoin(toAddress, satoshis) {
427
- const { request: request3 } = await import('sats-connect');
428
- const response = await request3("sendTransfer", {
429
- recipients: [
430
- {
431
- address: toAddress,
432
- amount: Number(satoshis)
433
- }
434
- ]
435
- });
436
- if (response.status === "error") {
437
- throw new Error(response.error?.message || "Xverse sendTransfer failed");
438
- }
439
- return response.result.txid;
440
- }
441
- };
442
- var XVERSE_ADDRESS_TYPE_KEY = "xverse-address-type";
443
- var XverseXConnector = class _XverseXConnector extends BitcoinXConnector {
444
- constructor() {
445
- super("Xverse", "xverse");
446
- const saved = typeof window !== "undefined" ? localStorage.getItem(XVERSE_ADDRESS_TYPE_KEY) : null;
447
- this.addressPurpose = saved === "segwit" ? AddressPurpose.Payment : AddressPurpose.Ordinals;
448
- }
449
- /** Set address purpose and persist to localStorage. */
450
- setAddressPurpose(type) {
451
- this.addressPurpose = type === "taproot" ? AddressPurpose.Ordinals : AddressPurpose.Payment;
452
- if (typeof window !== "undefined") {
453
- localStorage.setItem(XVERSE_ADDRESS_TYPE_KEY, type);
454
- }
455
- }
456
- static isAvailable() {
457
- return typeof window !== "undefined" && !!window.BitcoinProvider;
458
- }
459
- get icon() {
460
- return "https://cdn.brandfetch.io/iddzGN5Rcv/w/400/h/400/theme/dark/icon.jpeg?c=1bxid64Mup7aczewSAYMX&t=1771902357797";
461
- }
462
- async connect() {
463
- if (!_XverseXConnector.isAvailable()) {
464
- throw new Error("Xverse wallet is not installed");
465
- }
466
- const { request: request3 } = await import('sats-connect');
467
- const response = await request3("getAccounts", {
468
- purposes: [this.addressPurpose],
469
- message: "Connect to Sodax"
470
- });
471
- if (response.status === "error") {
472
- throw new Error(response.error?.message || "Xverse connection failed");
473
- }
474
- const accounts = response.result;
475
- const paymentAccount = accounts.find((a) => a.purpose === this.addressPurpose) || accounts[0];
476
- if (!paymentAccount) return void 0;
477
- this.walletProvider = new XverseWalletProvider(
478
- paymentAccount.address,
479
- paymentAccount.publicKey
480
- );
481
- return {
482
- address: paymentAccount.address,
483
- publicKey: paymentAccount.publicKey,
484
- xChainType: "BITCOIN"
485
- };
486
- }
487
- async disconnect() {
488
- this.walletProvider = void 0;
489
- }
490
- getWalletProvider() {
491
- return this.walletProvider;
492
- }
493
- recreateWalletProvider(xAccount) {
494
- if (!xAccount.address || !xAccount.publicKey) return void 0;
495
- return new XverseWalletProvider(xAccount.address, xAccount.publicKey);
496
- }
497
- };
498
- var OKXWalletProvider = class {
499
- constructor(okx, address) {
500
- this.okx = okx;
501
- this.cachedAddress = address;
502
- }
503
- async getWalletAddress() {
504
- try {
505
- const accounts = await this.okx.getAccounts();
506
- if (accounts[0]) this.cachedAddress = accounts[0];
507
- } catch {
508
- }
509
- return this.cachedAddress;
510
- }
511
- async getPublicKey() {
512
- return this.okx.getPublicKey();
513
- }
514
- async getAddressType(_address) {
515
- const address = await this.getWalletAddress();
516
- return detectBitcoinAddressType(address);
517
- }
518
- async signTransaction(psbtBase64, finalize = false) {
519
- const psbtHex = Buffer.from(psbtBase64, "base64").toString("hex");
520
- return this.okx.signPsbt(psbtHex, { autoFinalized: finalize });
521
- }
522
- async signEcdsaMessage(message) {
523
- return this.okx.signMessage(message, "ecdsa");
524
- }
525
- async signBip322Message(message) {
526
- return this.okx.signMessage(message, "bip322-simple");
527
- }
528
- async sendBitcoin(toAddress, satoshis) {
529
- if (satoshis > BigInt(Number.MAX_SAFE_INTEGER)) {
530
- throw new Error(`Amount ${satoshis} satoshis exceeds safe integer range`);
531
- }
532
- return this.okx.sendBitcoin(toAddress, Number(satoshis));
533
- }
534
- };
535
- var OKXXConnector = class extends BitcoinXConnector {
536
- constructor() {
537
- super("OKX Wallet", "okx-bitcoin");
538
- }
539
- static isAvailable() {
540
- return typeof window !== "undefined" && !!window.okxwallet?.bitcoin;
541
- }
542
- get icon() {
543
- return "https://static.okx.com/cdn/assets/imgs/247/58E63FEA47A2B7D7.png";
544
- }
545
- async connect() {
546
- const okx = window.okxwallet?.bitcoin;
547
- if (!okx) {
548
- throw new Error("OKX wallet is not installed");
549
- }
550
- const { address } = await okx.connect();
551
- if (!address) return void 0;
552
- this.walletProvider = new OKXWalletProvider(okx, address);
553
- return {
554
- address,
555
- xChainType: "BITCOIN"
556
- };
557
- }
558
- async disconnect() {
559
- this.walletProvider = void 0;
560
- }
561
- getWalletProvider() {
562
- return this.walletProvider;
563
- }
564
- recreateWalletProvider(xAccount) {
565
- const okx = window.okxwallet?.bitcoin;
566
- if (!okx || !xAccount.address) return void 0;
567
- return new OKXWalletProvider(okx, xAccount.address);
568
- }
569
- };
570
- var hyper = /* @__PURE__ */ defineChain({
571
- id: 999,
572
- name: "HyperEVM",
573
- nativeCurrency: {
574
- decimals: 18,
575
- name: "HYPE",
576
- symbol: "HYPE"
577
- },
578
- rpcUrls: {
579
- default: { http: ["https://rpc.hyperliquid.xyz/evm"] }
580
- },
581
- blockExplorers: {
582
- default: {
583
- name: "HyperEVMScan",
584
- url: "https://hyperevmscan.io/"
585
- }
586
- },
587
- contracts: {
588
- multicall3: {
589
- address: "0xcA11bde05977b3631167028862bE2a173976CA11",
590
- blockCreated: 13051
591
- }
592
- }
593
- });
594
- var createWagmiConfig = (config, options) => {
595
- return createConfig({
596
- chains: [
597
- mainnet,
598
- avalanche,
599
- arbitrum,
600
- base,
601
- bsc,
602
- sonic,
603
- optimism,
604
- polygon,
605
- hyper,
606
- lightlinkPhoenix,
607
- kaia,
608
- redbellyMainnet
609
- ],
610
- ssr: options?.ssr,
611
- transports: {
612
- [mainnet.id]: http(config[ETHEREUM_MAINNET_CHAIN_ID]),
613
- [avalanche.id]: http(config[AVALANCHE_MAINNET_CHAIN_ID]),
614
- [arbitrum.id]: http(config[ARBITRUM_MAINNET_CHAIN_ID]),
615
- [base.id]: http(config[BASE_MAINNET_CHAIN_ID]),
616
- [bsc.id]: http(config[BSC_MAINNET_CHAIN_ID]),
617
- [sonic.id]: http(config[SONIC_MAINNET_CHAIN_ID]),
618
- [optimism.id]: http(config[OPTIMISM_MAINNET_CHAIN_ID]),
619
- [polygon.id]: http(config[POLYGON_MAINNET_CHAIN_ID]),
620
- [hyper.id]: http(config[HYPEREVM_MAINNET_CHAIN_ID]),
621
- [lightlinkPhoenix.id]: http(config[LIGHTLINK_MAINNET_CHAIN_ID]),
622
- [redbellyMainnet.id]: http(config[REDBELLY_MAINNET_CHAIN_ID]),
623
- [kaia.id]: http(config[KAIA_MAINNET_CHAIN_ID])
624
- },
625
- storage: createStorage({
626
- storage: cookieStorage,
627
- key: "sodax"
628
- })
629
- });
630
- };
631
- var EvmXService = class _EvmXService extends XService {
632
- constructor() {
633
- super("EVM");
634
- }
635
- getXConnectors() {
636
- return [];
637
- }
638
- static getInstance() {
639
- if (!_EvmXService.instance) {
640
- _EvmXService.instance = new _EvmXService();
641
- }
642
- return _EvmXService.instance;
643
- }
644
- // get erc20 token balance in a chain (evm chain only)
645
- async _getTokenBalance(address, chainId, tokenAddress) {
646
- const publicClient = getPublicClient(this.wagmiConfig, { chainId });
647
- if (!publicClient) throw new Error("Public client not found");
648
- const balance = await publicClient.readContract({
649
- abi: erc20Abi,
650
- address: tokenAddress,
651
- functionName: "balanceOf",
652
- args: [address]
653
- });
654
- return balance || 0n;
655
- }
656
- //get native balance of the chain (evm chain only)
657
- async _getChainBalance(address, chainId) {
658
- const balance = await getPublicClient(this.wagmiConfig, { chainId })?.getBalance({
659
- address
660
- });
661
- return balance || 0n;
662
- }
663
- async getBalance(address, xToken) {
664
- if (!address) return 0n;
665
- if (!this.wagmiConfig) return 0n;
666
- const chainId = getWagmiChainId(xToken.xChainId);
667
- if (isNativeToken(xToken)) {
668
- return this._getChainBalance(address, chainId);
669
- }
670
- throw new Error(`Unsupported token: ${xToken.symbol}`);
671
- }
672
- async getBalances(address, xTokens) {
673
- if (!address) return {};
674
- if (!this.wagmiConfig) return {};
675
- const nativeTokenBalancePromises = xTokens.filter((xToken) => isNativeToken(xToken)).map(async (xToken) => {
676
- const balance = await this.getBalance(address, xToken);
677
- return { symbol: xToken.symbol, address: xToken.address, balance };
678
- });
679
- const nativeTokenBalances = await Promise.all(nativeTokenBalancePromises);
680
- const tokenMap = nativeTokenBalances.reduce((map, { address: address2, balance }) => {
681
- if (balance) map[address2] = balance;
682
- return map;
683
- }, {});
684
- const nonNativeXTokens = xTokens.filter((xToken) => !isNativeToken(xToken));
685
- const xChainId = xTokens[0].xChainId;
686
- const viemChain = this.wagmiConfig.chains.find((chain) => chain.id === getWagmiChainId(xChainId));
687
- const chainId = getWagmiChainId(xChainId);
688
- const publicClient = getPublicClient(this.wagmiConfig, { chainId });
689
- if (!publicClient) throw new Error("Public client not found");
690
- if (viemChain?.contracts?.multicall3) {
691
- const result = await publicClient.multicall({
692
- contracts: nonNativeXTokens.map((token) => ({
693
- abi: erc20Abi,
694
- address: token.address,
695
- functionName: "balanceOf",
696
- args: [address]
697
- }))
698
- });
699
- return nonNativeXTokens.reduce((acc, token, index) => {
700
- acc[token.address] = result?.[index]?.result?.toString() || "0";
701
- return acc;
702
- }, tokenMap);
703
- }
704
- const nonNativeTokenBalances = await Promise.all(
705
- nonNativeXTokens.map((token) => this._getTokenBalance(address, chainId, token.address))
706
- );
707
- return nonNativeXTokens.reduce((acc, token, idx) => {
708
- acc[token.address] = nonNativeTokenBalances[idx] || "0";
709
- return acc;
710
- }, tokenMap);
711
- }
712
- };
713
-
714
- // src/xchains/evm/EvmXConnector.ts
715
- var EvmXConnector = class extends XConnector {
716
- constructor(connector) {
717
- super("EVM", connector.name, connector.id);
718
- this.connector = connector;
719
- }
720
- async connect() {
721
- return;
722
- }
723
- async disconnect() {
724
- return;
725
- }
726
- get id() {
727
- return this.connector.id;
728
- }
729
- get icon() {
730
- return this.connector.icon;
731
- }
732
- };
733
- var InjectiveXService = class _InjectiveXService extends XService {
734
- constructor() {
735
- super("INJECTIVE");
736
- const endpoints = getNetworkEndpoints(Network.Mainnet);
737
- this.walletStrategy = new WalletStrategy({
738
- chainId: ChainId.Mainnet,
739
- strategies: {},
740
- evmOptions: {
741
- evmChainId: mainnet.id,
742
- rpcUrl: mainnet.rpcUrls.default.http[0]
743
- }
744
- });
745
- this.indexerGrpcAccountPortfolioApi = new IndexerGrpcAccountPortfolioApi(endpoints.indexer);
746
- this.chainGrpcWasmApi = new ChainGrpcWasmApi(endpoints.grpc);
747
- this.msgBroadcaster = new MsgBroadcaster({
748
- walletStrategy: this.walletStrategy,
749
- network: Network.Mainnet,
750
- endpoints
751
- });
752
- }
753
- static getInstance() {
754
- if (!_InjectiveXService.instance) {
755
- _InjectiveXService.instance = new _InjectiveXService();
756
- }
757
- return _InjectiveXService.instance;
758
- }
759
- async getBalance(address, xToken) {
760
- if (!address) return 0n;
761
- const portfolio = await this.indexerGrpcAccountPortfolioApi.fetchAccountPortfolioBalances(address);
762
- const xTokenAddress = xToken.address;
763
- const balance = portfolio.bankBalancesList.find((_balance) => _balance.denom === xTokenAddress);
764
- if (balance) {
765
- return BigInt(balance.amount);
766
- }
767
- return 0n;
768
- }
769
- };
770
- var WALLET_ICONS = {
771
- metamask: "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/metamask.svg",
772
- keplr: "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/keplr.svg",
773
- leap: "https://assets.leapwallet.io/logos/leap-cosmos-logo.svg",
774
- rabby: "https://raw.githubusercontent.com/RabbyHub/logo/master/symbol.svg",
775
- phantom: "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/phantom.svg",
776
- "okx-wallet": "https://static.okx.com/cdn/assets/imgs/247/58E63FEA47A2B7D7.png",
777
- "trust-wallet": "https://trustwallet.com/assets/images/media/assets/twLogo.svg"
778
- };
779
- var InjectiveXConnector = class extends XConnector {
780
- constructor(name, wallet) {
781
- super("INJECTIVE", name, wallet);
782
- this.wallet = wallet;
783
- }
784
- getXService() {
785
- return InjectiveXService.getInstance();
786
- }
787
- async connect() {
788
- if (isCosmosBrowserWallet(this.wallet) && !isCosmosWalletInstalled(this.wallet)) {
789
- return void 0;
790
- }
791
- const walletStrategy = this.getXService().walletStrategy;
792
- await walletStrategy.setWallet(this.wallet);
793
- const addresses = await walletStrategy.getAddresses();
794
- if (!addresses?.length) return void 0;
795
- const address = isEvmBrowserWallet(this.wallet) ? getInjectiveAddress(addresses[0]) : addresses[0];
796
- return {
797
- address,
798
- xChainType: this.xChainType
799
- };
800
- }
801
- async disconnect() {
802
- if (isEvmBrowserWallet(this.wallet)) {
803
- const walletStrategy = this.getXService().walletStrategy;
804
- await walletStrategy.setWallet(this.wallet);
805
- await walletStrategy.disconnect();
806
- }
807
- }
808
- get icon() {
809
- return WALLET_ICONS[this.wallet];
810
- }
811
- };
812
- var SolanaXService = class _SolanaXService extends XService {
813
- constructor() {
814
- super("SOLANA");
815
- }
816
- static getInstance() {
817
- if (!_SolanaXService.instance) {
818
- _SolanaXService.instance = new _SolanaXService();
819
- }
820
- return _SolanaXService.instance;
821
- }
822
- async getBalance(address, xToken) {
823
- if (!address) return BigInt(0);
824
- const connection = this.connection;
825
- if (!connection) {
826
- return BigInt(0);
827
- }
828
- try {
829
- if (isNativeToken(xToken)) {
830
- const newBalance = await connection.getBalance(new PublicKey(address));
831
- return BigInt(newBalance);
832
- }
833
- const tokenAccountPubkey = getAssociatedTokenAddressSync(new PublicKey(xToken.address), new PublicKey(address));
834
- const tokenAccount = await getAccount(connection, tokenAccountPubkey);
835
- return BigInt(tokenAccount.amount);
836
- } catch {
837
- return BigInt(0);
838
- }
839
- }
840
- };
841
- var CustomSorobanServer = class extends SorobanRpc.Server {
842
- constructor(serverUrl, customHeaders) {
843
- super(serverUrl, {
844
- allowHttp: true
845
- });
846
- this.customHeaders = customHeaders;
847
- }
848
- async simulateTransaction(tx) {
849
- const requestOptions = {
850
- method: "POST",
851
- headers: {
852
- "Content-Type": "application/json",
853
- ...this.customHeaders
854
- },
855
- body: JSON.stringify({
856
- id: 1,
857
- jsonrpc: "2.0",
858
- method: "simulateTransaction",
859
- params: {
860
- transaction: tx.toXDR()
861
- }
862
- })
863
- };
864
- const response = await fetch(`${this.serverURL}`, requestOptions);
865
- if (!response.ok) {
866
- throw new Error(`HTTP error simulating TX! status: ${response.status}`);
867
- }
868
- return response.json().then((json) => json.result);
869
- }
870
- async sendTransaction(tx) {
871
- const requestOptions = {
872
- method: "POST",
873
- headers: {
874
- "Content-Type": "application/json",
875
- ...this.customHeaders
876
- },
877
- body: JSON.stringify({
878
- id: 1,
879
- jsonrpc: "2.0",
880
- method: "sendTransaction",
881
- params: {
882
- transaction: tx.toXDR()
883
- }
884
- })
885
- };
886
- const response = await fetch(`${this.serverURL}`, requestOptions);
887
- if (!response.ok) {
888
- throw new Error(`HTTP error submitting TX! status: ${response.status}`);
889
- }
890
- return response.json().then((json) => json.result);
891
- }
892
- async getTransaction(hash) {
893
- const requestOptions = {
894
- method: "POST",
895
- headers: {
896
- "Content-Type": "application/json",
897
- ...this.customHeaders
898
- },
899
- body: JSON.stringify({
900
- id: 1,
901
- jsonrpc: "2.0",
902
- method: "getTransaction",
903
- params: { hash }
904
- })
905
- };
906
- const response = await fetch(`${this.serverURL}`, requestOptions);
907
- if (!response.ok) {
908
- throw new Error(`HTTP error getting TX! status: ${response.status}`);
909
- }
910
- return response.json().then((json) => json.result);
911
- }
912
- };
913
- var CustomSorobanServer_default = CustomSorobanServer;
914
- var accountToScVal = (account) => new Address(account).toScVal();
915
- var simulateTx = async (tx, server) => {
916
- const response = await server.simulateTransaction(tx);
917
- if (response !== void 0) {
918
- return response;
919
- }
920
- throw new Error("cannot simulate transaction");
921
- };
922
- var getTokenBalance = async (address, tokenId, txBuilder, server) => {
923
- const params = [accountToScVal(address)];
924
- const contract = new Contract(tokenId);
925
- const tx = txBuilder.addOperation(contract.call("balance", ...params)).setTimeout(TimeoutInfinite).build();
926
- const result = await simulateTx(tx, server);
927
- return result.results ? scValToBigInt(xdr.ScVal.fromXDR(result.results[0].xdr, "base64")) : 0n;
928
- };
929
-
930
- // src/xchains/stellar/StellarXService.ts
931
- var STELLAR_BASE_RESERVE_STROOPS = 5e6;
932
- function parseXlmBalanceToStroops(balanceStr) {
933
- const parts = balanceStr.split(".");
934
- const whole = parts[0] ?? "0";
935
- const frac = (parts[1] ?? "").padEnd(7, "0").slice(0, 7);
936
- return BigInt(whole + frac);
937
- }
938
- var StellarXService = class _StellarXService extends XService {
939
- constructor() {
940
- super("STELLAR");
941
- this.walletsKit = new StellarWalletsKit({
942
- network: WalletNetwork.PUBLIC,
943
- modules: allowAllModules()
944
- });
945
- this.server = new StellarSdk.Horizon.Server("https://horizon.stellar.org", { allowHttp: true });
946
- this.sorobanServer = new CustomSorobanServer_default("https://rpc.ankr.com/stellar_soroban", {});
947
- }
948
- static getInstance() {
949
- if (!_StellarXService.instance) {
950
- _StellarXService.instance = new _StellarXService();
951
- }
952
- return _StellarXService.instance;
953
- }
954
- async getBalance(address, xToken) {
955
- if (!address) return BigInt(0);
956
- const stellarAccount = await this.server.loadAccount(address);
957
- if (xToken.symbol === "XLM") {
958
- const xlmBalance = stellarAccount.balances.find((balance) => balance.asset_type === "native");
959
- if (xlmBalance) {
960
- const rawBalanceStroops = parseXlmBalanceToStroops(xlmBalance.balance);
961
- const sellingLiabilitiesStroops = xlmBalance.selling_liabilities ? parseXlmBalanceToStroops(xlmBalance.selling_liabilities) : BigInt(0);
962
- const reserveFields = stellarAccount;
963
- const subentryCount = reserveFields.subentry_count ?? 0;
964
- const numSponsoring = reserveFields.num_sponsoring ?? 0;
965
- const numSponsored = reserveFields.num_sponsored ?? 0;
966
- const reserveCount = Math.max(0, 2 + subentryCount + numSponsoring - numSponsored);
967
- const minBalanceStroops = BigInt(reserveCount) * BigInt(STELLAR_BASE_RESERVE_STROOPS) + sellingLiabilitiesStroops;
968
- const availableStroops = rawBalanceStroops > minBalanceStroops ? rawBalanceStroops - minBalanceStroops : BigInt(0);
969
- return availableStroops;
970
- }
971
- } else {
972
- try {
973
- const txBuilder = new StellarSdk.TransactionBuilder(stellarAccount, {
974
- fee: StellarSdk.BASE_FEE,
975
- networkPassphrase: StellarSdk.Networks.PUBLIC
976
- });
977
- const balance = await getTokenBalance(address, xToken.address, txBuilder, this.sorobanServer);
978
- return balance;
979
- } catch (e) {
980
- console.error(`Error while fetching token on Stellar: ${xToken.symbol}, Error: ${e}`);
981
- }
982
- }
983
- return BigInt(0);
984
- }
985
- };
986
-
987
- // src/xchains/stellar/StellarWalletsKitXConnector.ts
988
- var StellarWalletsKitXConnector = class extends XConnector {
989
- constructor(wallet) {
990
- super("STELLAR", wallet.name, wallet.id);
991
- this._wallet = wallet;
992
- }
993
- getXService() {
994
- return StellarXService.getInstance();
995
- }
996
- async connect() {
997
- const kit = this.getXService().walletsKit;
998
- if (!this._wallet) {
999
- return;
1000
- }
1001
- if (!this._wallet.isAvailable && this._wallet.url) {
1002
- window.open(this._wallet.url, "_blank");
1003
- return;
1004
- }
1005
- kit.setWallet(this._wallet.id);
1006
- const { address } = await kit.getAddress();
1007
- return {
1008
- address,
1009
- xChainType: this.xChainType
1010
- };
1011
- }
1012
- async disconnect() {
1013
- }
1014
- get icon() {
1015
- return this._wallet.icon;
1016
- }
1017
- };
1018
-
1019
- // src/xchains/sui/SuiXService.ts
1020
- var SuiXService = class _SuiXService extends XService {
1021
- // TODO: define suiAccount type
1022
- constructor() {
1023
- super("SUI");
1024
- }
1025
- static getInstance() {
1026
- if (!_SuiXService.instance) {
1027
- _SuiXService.instance = new _SuiXService();
1028
- }
1029
- return _SuiXService.instance;
1030
- }
1031
- // getBalance is not used because getBalances uses getAllBalances which returns all balances
1032
- async getBalances(address, xTokens) {
1033
- if (!address) return {};
1034
- try {
1035
- const balancePromises = xTokens.map(async (xToken) => {
1036
- let coinType = isNativeToken(xToken) ? "0x2::sui::SUI" : xToken.address;
1037
- if (coinType === "0x03917a812fe4a6d6bc779c5ab53f8a80ba741f8af04121193fc44e0f662e2ceb::balanced_dollar::BALANCED_DOLLAR") {
1038
- coinType = "0x3917a812fe4a6d6bc779c5ab53f8a80ba741f8af04121193fc44e0f662e2ceb::balanced_dollar::BALANCED_DOLLAR";
1039
- }
1040
- const balance = await this.suiClient.getBalance({
1041
- owner: address,
1042
- coinType
1043
- });
1044
- return {
1045
- address: xToken.address,
1046
- balance: balance ? BigInt(balance.totalBalance) : void 0
1047
- };
1048
- });
1049
- const results = await Promise.all(balancePromises);
1050
- const tokenMap = {};
1051
- results.forEach((result) => {
1052
- if (result.balance !== void 0) {
1053
- tokenMap[result.address] = result.balance;
1054
- }
1055
- });
1056
- return tokenMap;
1057
- } catch (e) {
1058
- console.log("error", e);
1059
- return {};
1060
- }
1061
- }
1062
- };
1063
-
1064
- // src/xchains/sui/SuiXConnector.ts
1065
- var SuiXConnector = class extends XConnector {
1066
- constructor(wallet) {
1067
- super("SUI", wallet?.name, wallet?.name);
1068
- this.wallet = wallet;
1069
- }
1070
- getXService() {
1071
- return SuiXService.getInstance();
1072
- }
1073
- async connect() {
1074
- return;
1075
- }
1076
- async disconnect() {
1077
- }
1078
- get icon() {
1079
- return this.wallet?.icon;
1080
- }
1081
- };
1082
- var IconSdk = "default" in IconSdkRaw.default ? IconSdkRaw.default : IconSdkRaw;
1083
- var { IconService: IconServiceConstructor, Builder: IconBuilder, Converter: IconConverter } = IconSdk;
1084
- var CHAIN_INFO = {
1085
- [1 /* MAINNET */]: {
1086
- APIEndpoint: "https://ctz.solidwallet.io/api/v3"}
1087
- };
1088
- var IconXService = class _IconXService extends XService {
1089
- constructor() {
1090
- super("ICON");
1091
- this.iconService = new IconServiceConstructor(
1092
- new IconServiceConstructor.HttpProvider(CHAIN_INFO[1 /* MAINNET */].APIEndpoint)
1093
- );
1094
- }
1095
- static getInstance() {
1096
- if (!_IconXService.instance) {
1097
- _IconXService.instance = new _IconXService();
1098
- }
1099
- return _IconXService.instance;
1100
- }
1101
- async getAggregateData(requireSuccess, calls) {
1102
- const rawTx = new IconBuilder.CallBuilder().to("cxa4aa9185e23558cff990f494c1fd2845f6cbf741").method("tryAggregate").params({ requireSuccess: IconConverter.toHex(requireSuccess ? 1 : 0), calls }).build();
1103
- try {
1104
- const result = await this.iconService.call(rawTx).execute();
1105
- const aggs = result["returnData"];
1106
- const data = aggs.map((agg) => {
1107
- if (agg["success"] === "0x0") {
1108
- return null;
1109
- }
1110
- return agg["returnData"];
1111
- });
1112
- return data;
1113
- } catch (err) {
1114
- console.error(err);
1115
- return Array(calls.length).fill(null);
1116
- }
1117
- }
1118
- async getBalances(address, xTokens) {
1119
- if (!address) return {};
1120
- const balances = {};
1121
- const nativeXToken = xTokens.find((xToken) => isNativeToken(xToken));
1122
- const nonNativeXTokens = xTokens.filter((xToken) => !isNativeToken(xToken));
1123
- if (nativeXToken) {
1124
- const balance = await this.iconService.getBalance(address).execute();
1125
- balances[nativeXToken.address] = BigInt(balance.toFixed());
1126
- }
1127
- const cds = nonNativeXTokens.map((token) => {
1128
- return {
1129
- target: token.address,
1130
- method: "balanceOf",
1131
- params: [address]
1132
- };
1133
- });
1134
- const data = await this.getAggregateData(
1135
- false,
1136
- cds.filter((cd) => cd.target.startsWith("cx"))
1137
- );
1138
- return nonNativeXTokens.reduce((agg, token, idx) => {
1139
- const balance = data[idx];
1140
- balances[token.address] = BigInt(balance);
1141
- return agg;
1142
- }, balances);
1143
- }
1144
- };
1145
-
1146
- // src/xchains/icon/iconex/index.tsx
1147
- var ICONEX_RELAY_RESPONSE = "ICONEX_RELAY_RESPONSE";
1148
- var ICONEX_RELAY_REQUEST = "ICONEX_RELAY_REQUEST";
1149
- var request = (event) => {
1150
- return new Promise((resolve, reject) => {
1151
- const handler = (evt) => {
1152
- window.removeEventListener(ICONEX_RELAY_RESPONSE, handler);
1153
- resolve(evt.detail);
1154
- };
1155
- window.addEventListener(ICONEX_RELAY_RESPONSE, handler);
1156
- window.dispatchEvent(
1157
- new CustomEvent(ICONEX_RELAY_REQUEST, {
1158
- detail: event
1159
- })
1160
- );
1161
- });
1162
- };
1163
-
1164
- // src/xchains/icon/IconHanaXConnector.ts
1165
- var IconHanaXConnector = class extends XConnector {
1166
- constructor() {
1167
- super("ICON", "Hana Wallet", "hana");
1168
- }
1169
- async connect() {
1170
- const { hanaWallet } = window;
1171
- if (window && !hanaWallet && !hanaWallet?.isAvailable) {
1172
- window.open("https://chromewebstore.google.com/detail/hana-wallet/jfdlamikmbghhapbgfoogdffldioobgl", "_blank");
1173
- return;
1174
- }
1175
- const detail = await request({
1176
- type: "REQUEST_ADDRESS" /* REQUEST_ADDRESS */
1177
- });
1178
- if (detail?.type === "RESPONSE_ADDRESS" /* RESPONSE_ADDRESS */) {
1179
- return {
1180
- address: detail?.payload,
1181
- xChainType: this.xChainType
1182
- };
1183
- }
1184
- return void 0;
1185
- }
1186
- async disconnect() {
1187
- console.log("HanaIconXConnector disconnected");
1188
- }
1189
- get icon() {
1190
- return "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/hana.svg";
1191
- }
1192
- };
1193
- function getProviderFromId(id) {
1194
- return id.split(".").reduce((acc, part) => acc?.[part], window);
1195
- }
1196
- var StacksXConnector = class extends XConnector {
1197
- constructor(config) {
1198
- super("STACKS", config.name, config.id);
1199
- this.config = config;
1200
- }
1201
- async connect() {
1202
- const provider = this.getProvider();
1203
- if (!provider) {
1204
- if (this.config.installUrl) {
1205
- window.open(this.config.installUrl, "_blank");
1206
- }
1207
- return void 0;
1208
- }
1209
- const response = await request$1({ provider }, "stx_getAddresses");
1210
- const stxAddress = response.addresses.find((a) => a.purpose === "stacks");
1211
- if (!stxAddress) {
1212
- return void 0;
1213
- }
1214
- return {
1215
- address: stxAddress.address,
1216
- xChainType: this.xChainType
1217
- };
1218
- }
1219
- async disconnect() {
1220
- disconnect();
1221
- }
1222
- get icon() {
1223
- return this.config.icon;
1224
- }
1225
- getProvider() {
1226
- return getProviderFromId(this.config.id);
1227
- }
1228
- };
1229
-
1230
- // src/xchains/stacks/constants.ts
1231
- var LEATHER_ICON = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCIgdmlld0JveD0iMCAwIDEyOCAxMjgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxMjgiIGhlaWdodD0iMTI4IiByeD0iMjYuODM4NyIgZmlsbD0iIzEyMTAwRiIvPgo8cGF0aCBkPSJNNzQuOTE3MSA1Mi43MTE0QzgyLjQ3NjYgNTEuNTQwOCA5My40MDg3IDQzLjU4MDQgOTMuNDA4NyAzNy4zNzYxQzkzLjQwODcgMzUuNTAzMSA5MS44OTY4IDM0LjIxNTQgODkuNjg3MSAzNC4yMTU0Qzg1LjUwMDQgMzQuMjE1NCA3OC40MDYxIDQwLjUzNjggNzQuOTE3MSA1Mi43MTE0Wk0zOS45MTEgODMuNDk5MUMzMC4wMjU2IDgzLjQ5OTEgMjkuMjExNSA5My4zMzI0IDM5LjA5NjkgOTMuMzMyNEM0My41MTYzIDkzLjMzMjQgNDguODY2MSA5MS41NzY0IDUxLjY1NzMgODguNDE1N0M0Ny41ODY4IDg0LjkwMzggNDQuMjE0MSA4My40OTkxIDM5LjkxMSA4My40OTkxWk0xMDIuODI5IDc5LjI4NDhDMTAzLjQxIDk1Ljc5MDcgOTUuMDM2OSAxMDUuMDM5IDgwLjg0ODQgMTA1LjAzOUM3Mi40NzQ4IDEwNS4wMzkgNjguMjg4MSAxMDEuODc4IDU5LjMzMyA5Ni4wMjQ5QzU0LjY4MSAxMDEuMTc2IDQ1Ljg0MjMgMTA1LjAzOSAzOC41MTU0IDEwNS4wMzlDMTMuMjc4NSAxMDUuMDM5IDE0LjMyNTIgNzIuODQ2MyA0MC4wMjczIDcyLjg0NjNDNDUuMzc3MSA3Mi44NDYzIDQ5LjkxMjggNzQuMjUxMSA1NS43Mjc3IDc3Ljg4TDU5LjU2NTYgNjQuNDE3N0M0My43NDg5IDYwLjA4NjQgMzUuODQwNSA0Ny45MTE4IDQzLjYzMjYgMzAuNDY5M0g1Ni4xOTI5QzQ5LjIxNSA0Mi4wNTg2IDUzLjk4MzIgNTEuNjU3OCA2Mi44MjIgNTIuNzExNEM2Ny41OTAzIDM1LjczNzIgNzcuODI0NiAyMi41MDkgOTEuNDMxNiAyMi41MDlDOTkuMTA3NCAyMi41MDkgMTA1LjE1NSAyNy41NDI4IDEwNS4xNTUgMzYuNjczN0MxMDUuMTU1IDUxLjMwNjYgODYuMDgxOSA2My4yNDcxIDcxLjY2MDcgNjQuNDE3N0w2NS43Mjk1IDg1LjM3MjFDNzIuNDc0OCA5My4yMTUzIDkxLjE5OSAxMDAuODI0IDkxLjE5OSA3OS4yODQ4SDEwMi44MjlaIiBmaWxsPSIjRjVGMUVEIi8+Cjwvc3ZnPgo=";
1232
- var XVERSE_ICON = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MDAiIGhlaWdodD0iNjAwIj48ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGZpbGw9IiMxNzE3MTciIGQ9Ik0wIDBoNjAwdjYwMEgweiIvPjxwYXRoIGZpbGw9IiNGRkYiIGZpbGwtcnVsZT0ibm9uemVybyIgZD0iTTQ0MCA0MzUuNHYtNTFjMC0yLS44LTMuOS0yLjItNS4zTDIyMCAxNjIuMmE3LjYgNy42IDAgMCAwLTUuNC0yLjJoLTUxLjFjLTIuNSAwLTQuNiAyLTQuNiA0LjZ2NDcuM2MwIDIgLjggNCAyLjIgNS40bDc4LjIgNzcuOGE0LjYgNC42IDAgMCAxIDAgNi41bC03OSA3OC43Yy0xIC45LTEuNCAyLTEuNCAzLjJ2NTJjMCAyLjQgMiA0LjUgNC42IDQuNUgyNDljMi42IDAgNC42LTIgNC42LTQuNlY0MDVjMC0xLjIuNS0yLjQgMS40LTMuM2w0Mi40LTQyLjJhNC42IDQuNiAwIDAgMSA2LjQgMGw3OC43IDc4LjRhNy42IDcuNiAwIDAgMCA1LjQgMi4yaDQ3LjVjMi41IDAgNC42LTIgNC42LTQuNloiLz48cGF0aCBmaWxsPSIjRUU3QTMwIiBmaWxsLXJ1bGU9Im5vbnplcm8iIGQ9Ik0zMjUuNiAyMjcuMmg0Mi44YzIuNiAwIDQuNiAyLjEgNC42IDQuNnY0Mi42YzAgNCA1IDYuMSA4IDMuMmw1OC43LTU4LjVjLjgtLjggMS4zLTIgMS4zLTMuMnYtNTEuMmMwLTIuNi0yLTQuNi00LjYtNC42TDM4NCAxNjBjLTEuMiAwLTIuNC41LTMuMyAxLjNsLTU4LjQgNTguMWE0LjYgNC42IDAgMCAwIDMuMiA3LjhaIi8+PC9nPjwvc3ZnPg==";
1233
- var ASIGNA_ICON = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMDEwMCIgZD0iTTAgMGgzMnYzMkgweiIvPjxwYXRoIGZpbGw9InVybCgjYSkiIGQ9Ik0xNS4xMSA1LjU1YTMgMyAwIDAgMC0xLjgyIDEuM2wtLjA1LjA4LS40My43Mi0uMDcuMTEtLjUuODUtLjA1LjA5LTEuMjkgMi4xOC0uMDQuMDctLjQ3LjgtLjA2LjEtLjQ2Ljc4LS4wNy4xMS0xLjYzIDIuNzYtLjA3LjExLS4zOC42Ni0uMDUuMDgtLjczIDEuMjQtLjM1LjYtLjQuNjctLjA1LjA5TDUuMSAyMC43bC0uMTEuMTgtLjE0LjIzLS4wNy4xMy0uMzMuNTUtLjA0LjA3di4wMWExLjI2IDEuMjYgMCAwIDAtLjE0LjQ3IDEuMzEgMS4zMSAwIDAgMCAxLjI0IDEuNGgxLjVsLjA1LS4wNi4wNC0uMDYuODctMS4yMS4wNS0uMDguNzctMS4wNy4wNS0uMDcuNC0uNTcuMDUtLjA2LjI0LS4zNGExLjUyIDEuNTIgMCAwIDEgMS4zOS0uNjIgMS41IDEuNSAwIDAgMSAuNjQuMiAxLjQ3IDEuNDcgMCAwIDEgLjczIDEuMjcgMS40NCAxLjQ0IDAgMCAxLS4yNy44NGwtLjYzLjg4LS4wNS4wNy0uMzIuNDUtLjA2LjA4LS4wOC4xMi0uMTIuMTYtLjA1LjA4aDIuMTNhMi4zMiAyLjMyIDAgMCAwIDEuNzctLjk2bDEuMTgtMS42My43Ny0xLjA4IDEuMy0xLjhhMS4yNCAxLjI0IDAgMCAxIC41NS0uNDNsLjA4LS4wM2ExLjMgMS4zIDAgMCAxIC4zLS4wNiAxLjI4IDEuMjggMCAwIDEgMS4xNS41NGwuMTEuMmExLjEzIDEuMTMgMCAwIDEgLjEuNDEgMS4xOSAxLjE5IDAgMCAxLS4yMy43N2wtLjAzLjA1LS41Ny44LS43Ljk4LS4yNy4zN2ExLjIyIDEuMjIgMCAwIDAtLjIuNSAxLjA1IDEuMDUgMCAwIDAtLjAyLjIzdi4wNmExLjE3IDEuMTcgMCAwIDAgLjE0LjQzbC4wMi4wNS4wNy4xYTEuNDQgMS40NCAwIDAgMCAuMS4xMWwuMDUuMDYuMDEuMDFhMS44IDEuOCAwIDAgMCAuMTQuMWMwIC4wMi4wMi4wMy4wNC4wM2ExIDEgMCAwIDAgLjA4LjA1bC4wNy4wNGExLjI1IDEuMjUgMCAwIDAgLjUuMWg2LjljLjEgMCAuMi0uMDEuMjktLjAzbC4wNi0uMDJhMS4yNyAxLjI3IDAgMCAwIC4yNy0uMS41Ny41NyAwIDAgMCAuMDctLjAzIDEuMjEgMS4yMSAwIDAgMCAuMjYtLjE5bC4wOC0uMDdhLjkyLjkyIDAgMCAwIC4xNS0uMTkgMS41NSAxLjU1IDAgMCAwIC4wOS0uMTdsLjAyLS4wNWExLjIyIDEuMjIgMCAwIDAgLjA4LS4yNnYtLjA0bC4wMi0uMDh2LS4wOGExLjMyIDEuMzIgMCAwIDAtLjItLjc0bC0xLjYtMi42NC0uMDYtLjEtLjItLjMyLS4zMy0uNTR2LS4wMWwtLjA1LS4wOC0xLjMtMi4xNS0uMDctLjEtLjA0LS4wNi0uOC0xLjMyLS4wNC0uMDctLjItLjM0LS4xLS4xNC0uMS0uMTYtLjUzLS45LS4xMy0uMi0uMDktLjE0LTIuMTctMy41Ny0uMDQtLjA3LS43Mi0xLjE5LS4wNS0uMDctLjQtLjY1YTIuNjUgMi42NSAwIDAgMC0uMy0uNCAyLjk2IDIuOTYgMCAwIDAtLjk3LS43NCAzLjA0IDMuMDQgMCAwIDAtMS4zLS4zYy0uMjUgMC0uNS4wNC0uNzQuMVoiLz48cGF0aCBmaWxsPSJ1cmwoI2IpIiBkPSJNMTkgMTYuM2E1LjQ1IDUuNDUgMCAwIDAtLjgzIDEuNTZsLS4wNC4xNWExLjM2IDEuMzYgMCAwIDEgLjI4LS4xNiAxLjI0IDEuMjQgMCAwIDEgLjM4LS4wOGguMWExLjI4IDEuMjggMCAwIDEgMS4wNS41NGMuMDQuMDYuMDguMTMuMS4yYTEuMjQgMS4yNCAwIDAgMSAuMDkuMjcgMS4xOSAxLjE5IDAgMCAxLS4yLjkxbC0uMDQuMDUtLjU3Ljc5LS43Ljk5LS4yNy4zN2ExLjIzIDEuMjMgMCAwIDAtLjIuNDIgMS4wNiAxLjA2IDAgMCAwLS4wMi4zMXYuMDZhMS4xNyAxLjE3IDAgMCAwIC4xNi40Ny45My45MyAwIDAgMCAuMDcuMSAxLjUgMS41IDAgMCAwIC4xLjEybC4wNS4wNmguMDFhMS45NCAxLjk0IDAgMCAwIC4wOS4wOCAxIDEgMCAwIDAgLjE3LjFsLjA3LjA0YTEuMjUgMS4yNSAwIDAgMCAuNS4xaDYuOWMuMSAwIC4yIDAgLjI4LS4wMmwuMDctLjAyYTEuMzIgMS4zMiAwIDAgMCAuMzQtLjEzbC4xNi0uMS4wMy0uMDNhMS4yOSAxLjI5IDAgMCAwIC4yLS4yIDIuNDMgMi40MyAwIDAgMCAuMTItLjE3Yy4wMy0uMDMuMDUtLjA4LjA3LS4xMmwuMDItLjA1YTEuMjEgMS4yMSAwIDAgMCAuMDktLjN2LS4wOGwuMDEtLjA5YTEuMzIgMS4zMiAwIDAgMC0uMi0uNzNsLTEuNi0yLjY0LS4wNi0uMS0uMi0uMzItLjMzLS41NHYtLjAybC0uMDUtLjA3LTEuMy0yLjE1LS4xMi0uMDctLjA3LS4wNGE0Ljk0IDQuOTQgMCAwIDAtMi40Ni0uNjdjLTEuMDMgMC0xLjc2LjU3LTIuMjYgMS4yWiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMi4yOSAyMS4wOGMwIC4yOS0uMDkuNTgtLjI3Ljg0bC0xLjMxIDEuODRIN2wyLjUyLTMuNTNhMS41NCAxLjU0IDAgMCAxIDIuMS0uMzZjLjQzLjI4LjY2Ljc0LjY2IDEuMloiLz48cGF0aCBmaWxsPSIjMDAwIiBkPSJNMTEuMTYgMjEuMjVhLjU2LjU2IDAgMCAxLS41Ny41NS41Ni41NiAwIDAgMS0uNTctLjU2LjU2LjU2IDAgMCAxIC41Ny0uNTUuNTYuNTYgMCAwIDEgLjU3LjU2WiIvPjxkZWZzPjxsaW5lYXJHcmFkaWVudCBpZD0iYSIgeDE9IjE1LjIzIiB4Mj0iMTkuMyIgeTE9IjI1Ljc4IiB5Mj0iNi4xMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPjxzdG9wIHN0b3AtY29sb3I9IiM2NTIyRjQiLz48c3RvcCBvZmZzZXQ9Ii41NSIgc3RvcC1jb2xvcj0iIzlCNkJGRiIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0E1ODVGRiIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJiIiB4MT0iMjIuNTkiIHgyPSIyNC44IiB5MT0iMjQuNzEiIHkyPSIxNS41MyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPjxzdG9wIHN0b3AtY29sb3I9IiM0MjFGOEIiLz48c3RvcCBvZmZzZXQ9Ii41NSIgc3RvcC1jb2xvcj0iIzcyMzBGRiIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzk3NzNGRiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjwvc3ZnPg==";
1234
- var FORDEFI_ICON = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDIiIGhlaWdodD0iNDIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZmlsbD0iIzEwMTExNCIgZD0iTTAgMGg0MnY0MkgweiIvPgogIDxwYXRoIGQ9Ik0xOS40NyAyNi44OUg1djMuNTdhNC41NyA0LjU3IDAgMCAwIDQuNTggNC41N2g1LjgzbDQuMDYtOC4xNFoiIGZpbGw9IiM3OTk0RkYiLz4KICA8cGF0aCBkPSJNNSAxNy40aDI3LjU4bC0zLjIgNi43OEg1VjE3LjRaIiBmaWxsPSIjNDg2REZGIi8+CiAgPHBhdGggZD0iTTE0LjY3IDdINXY3LjY4aDMzVjdoLTkuNjd2NS43NGgtMlY3aC05LjY3djUuNzRoLTEuOTlWN1oiIGZpbGw9IiM1Q0QxRkEiLz4KPC9zdmc+Cg==";
1235
- var STACKS_PROVIDERS = [
1236
- {
1237
- id: "LeatherProvider",
1238
- name: "Leather",
1239
- icon: LEATHER_ICON,
1240
- installUrl: "https://chrome.google.com/webstore/detail/hiro-wallet/ldinpeekobnhjjdofggfgjlcehhmanlj"
1241
- },
1242
- {
1243
- id: "XverseProviders.BitcoinProvider",
1244
- name: "Xverse Wallet",
1245
- icon: XVERSE_ICON,
1246
- installUrl: "https://chrome.google.com/webstore/detail/xverse-wallet/idnnbdplmphpflfnlkomgpfbpcgelopg"
1247
- },
1248
- {
1249
- id: "AsignaProvider",
1250
- name: "Asigna Multisig",
1251
- icon: ASIGNA_ICON,
1252
- installUrl: "https://stx.asigna.io/"
1253
- },
1254
- {
1255
- id: "FordefiProviders.UtxoProvider",
1256
- name: "Fordefi",
1257
- icon: FORDEFI_ICON,
1258
- installUrl: "https://chromewebstore.google.com/detail/fordefi/hcmehenccjdmfbojapcbcofkgdpbnlle"
1259
- }
1260
- ];
1261
- function useStacksXConnectors() {
1262
- return useMemo(() => STACKS_PROVIDERS.map((config) => new StacksXConnector(config)), []);
1263
- }
1264
-
1265
- // src/useXWagmiStore.ts
1266
- var initXServices = () => {
1267
- const xServices = {};
1268
- ["EVM", "BITCOIN", "INJECTIVE", "STELLAR", "SUI", "SOLANA", "ICON", "NEAR", "STACKS"].forEach((key) => {
1269
- const xChainType = key;
1270
- switch (xChainType) {
1271
- // EVM, SUI, Solana wallet connectors are supported by their own sdks. wagmi, @mysten/dapp-kit, @solana/wallet-adapter-react.
1272
- case "EVM":
1273
- xServices[xChainType] = EvmXService.getInstance();
1274
- xServices[xChainType].setXConnectors([]);
1275
- break;
1276
- case "SUI":
1277
- xServices[xChainType] = SuiXService.getInstance();
1278
- xServices[xChainType].setXConnectors([]);
1279
- break;
1280
- case "SOLANA":
1281
- xServices[xChainType] = SolanaXService.getInstance();
1282
- xServices[xChainType].setXConnectors([]);
1283
- break;
1284
- case "BITCOIN":
1285
- xServices[xChainType] = BitcoinXService.getInstance();
1286
- xServices[xChainType].setXConnectors([new UnisatXConnector(), new XverseXConnector(), new OKXXConnector()]);
1287
- break;
1288
- // Injective, Stellar, Icon wallet connectors are supported by sodax wallet-sdk-react sdk.
1289
- case "INJECTIVE":
1290
- xServices[xChainType] = InjectiveXService.getInstance();
1291
- xServices[xChainType].setXConnectors([
1292
- // EVM wallets (auto-detected via EIP-6963)
1293
- new InjectiveXConnector("MetaMask", Wallet.Metamask),
1294
- // Cosmos wallets (detected via window globals)
1295
- new InjectiveXConnector("Keplr", Wallet.Keplr),
1296
- new InjectiveXConnector("Leap", Wallet.Leap)
1297
- ]);
1298
- break;
1299
- case "STELLAR":
1300
- xServices[xChainType] = StellarXService.getInstance();
1301
- xServices[xChainType].setXConnectors([]);
1302
- break;
1303
- case "ICON":
1304
- xServices[xChainType] = IconXService.getInstance();
1305
- xServices[xChainType].setXConnectors([new IconHanaXConnector()]);
1306
- break;
1307
- case "NEAR":
1308
- xServices[xChainType] = NearXService.getInstance();
1309
- xServices[xChainType].setXConnectors([]);
1310
- break;
1311
- case "STACKS":
1312
- xServices[xChainType] = StacksXService.getInstance();
1313
- xServices[xChainType].setXConnectors(STACKS_PROVIDERS.map((config) => new StacksXConnector(config)));
1314
- break;
31
+ var EvmHydrator = () => {
32
+ const wagmiConfig = useConfig();
33
+ const connectors = useConnectors();
34
+ const { address, status, connector } = useAccount();
35
+ const evmPublicClient = usePublicClient();
36
+ const { data: evmWalletClient } = useWalletClient();
37
+ const setXConnection = useXWalletStore((state) => state.setXConnection);
38
+ const unsetXConnection = useXWalletStore((state) => state.unsetXConnection);
39
+ const setWalletProvider = useXWalletStore((state) => state.setWalletProvider);
40
+ const userDisconnectedEvm = useXWalletStore((state) => state.userDisconnected.EVM);
41
+ const { reconnect } = useReconnect();
42
+ const walletConfig = useWalletConfig();
43
+ useEffect(() => {
44
+ if (wagmiConfig) {
45
+ EvmXService.getInstance().wagmiConfig = wagmiConfig;
1315
46
  }
1316
- });
1317
- return xServices;
47
+ }, [wagmiConfig]);
48
+ const evmConnectors = useMemo(() => connectors.map((c) => new EvmXConnector(c)), [connectors]);
49
+ useEffect(() => {
50
+ EvmXService.getInstance().setXConnectors(evmConnectors);
51
+ useXWalletStore.getState().setXConnectors("EVM", evmConnectors);
52
+ }, [evmConnectors]);
53
+ const [hydrated, setHydrated] = useState(() => useXWalletStore.persist.hasHydrated());
54
+ useEffect(() => {
55
+ if (hydrated) return;
56
+ const unsub = useXWalletStore.persist.onFinishHydration(() => setHydrated(true));
57
+ return unsub;
58
+ }, [hydrated]);
59
+ useEffect(() => {
60
+ if (!hydrated) return;
61
+ if (status !== "disconnected") return;
62
+ const state = useXWalletStore.getState();
63
+ if (!state.xConnections.EVM) return;
64
+ if (state.userDisconnected.EVM) return;
65
+ reconnect();
66
+ }, [hydrated, connectors, status, reconnect]);
67
+ const wasConnectedRef = useRef(false);
68
+ useEffect(() => {
69
+ if (status === "connecting" || status === "reconnecting") return;
70
+ if (status === "connected" && address && connector) {
71
+ if (userDisconnectedEvm) return;
72
+ wasConnectedRef.current = true;
73
+ setXConnection("EVM", {
74
+ xAccount: { address, xChainType: "EVM" },
75
+ xConnectorId: connector.id
76
+ });
77
+ } else if (status === "disconnected" && wasConnectedRef.current) {
78
+ wasConnectedRef.current = false;
79
+ unsetXConnection("EVM");
80
+ }
81
+ }, [address, status, connector, userDisconnectedEvm, setXConnection, unsetXConnection]);
82
+ const walletProvider = useMemo(() => {
83
+ if (!evmPublicClient || !evmWalletClient) return void 0;
84
+ if (userDisconnectedEvm) return void 0;
85
+ const defaults = resolveEvmDefaults(evmWalletClient.chain.id, walletConfig.EVM?.chains);
86
+ return new EvmWalletProvider({
87
+ walletClient: evmWalletClient,
88
+ publicClient: evmPublicClient,
89
+ defaults
90
+ });
91
+ }, [evmPublicClient, evmWalletClient, walletConfig.EVM?.chains, userDisconnectedEvm]);
92
+ useEffect(() => {
93
+ setWalletProvider("EVM", walletProvider);
94
+ }, [walletProvider, setWalletProvider]);
95
+ return null;
1318
96
  };
1319
- var useXWagmiStore = create()(
1320
- devtools(
1321
- persist(
1322
- immer((set, get) => ({
1323
- xServices: initXServices(),
1324
- xConnections: {},
1325
- setXConnection: (xChainType, xConnection) => {
1326
- set((state) => {
1327
- state.xConnections[xChainType] = xConnection;
1328
- });
1329
- },
1330
- unsetXConnection: (xChainType) => {
1331
- set((state) => {
1332
- delete state.xConnections[xChainType];
1333
- });
1334
- }
1335
- })),
1336
- {
1337
- name: "xwagmi-store",
1338
- storage: createJSONStorage(() => localStorage),
1339
- partialize: (state) => ({ xConnections: state.xConnections })
1340
- }
1341
- ),
1342
- { name: "xwagmi-store" }
1343
- )
1344
- );
1345
-
1346
- // src/hooks/useXConnection.ts
1347
- function useXConnection(xChainType) {
1348
- const xConnection = useXWagmiStore((state) => xChainType ? state.xConnections?.[xChainType] : void 0);
1349
- const evmConnections = useConnections();
1350
- const { address: evmAddress } = useAccount();
1351
- const suiAccount = useCurrentAccount();
1352
- const suiCurrentWallet = useCurrentWallet();
1353
- const solanaWallet = useWallet();
1354
- const xConnection2 = useMemo(() => {
1355
- if (!xChainType) {
1356
- return void 0;
1357
- }
1358
- switch (xChainType) {
1359
- case "EVM":
1360
- return {
1361
- xAccount: { address: evmAddress, xChainType },
1362
- xConnectorId: evmConnections?.[0]?.connector.id
1363
- };
1364
- case "SUI":
1365
- if (suiCurrentWallet.currentWallet && suiCurrentWallet.connectionStatus === "connected") {
1366
- return {
1367
- xAccount: { address: suiAccount?.address, xChainType },
1368
- xConnectorId: suiCurrentWallet.currentWallet.name
1369
- };
97
+ var EvmActions = () => {
98
+ const wagmiConfig = useConfig();
99
+ const { connectAsync } = useConnect();
100
+ const { disconnectAsync } = useDisconnect();
101
+ const { signMessageAsync } = useSignMessage();
102
+ const registerChainActions = useXWalletStore((state) => state.registerChainActions);
103
+ const connectRef = useRef(connectAsync);
104
+ const disconnectRef = useRef(disconnectAsync);
105
+ const signMessageRef = useRef(signMessageAsync);
106
+ const wagmiConfigRef = useRef(wagmiConfig);
107
+ useEffect(() => {
108
+ connectRef.current = connectAsync;
109
+ disconnectRef.current = disconnectAsync;
110
+ signMessageRef.current = signMessageAsync;
111
+ wagmiConfigRef.current = wagmiConfig;
112
+ }, [connectAsync, disconnectAsync, signMessageAsync, wagmiConfig]);
113
+ useEffect(() => {
114
+ registerChainActions("EVM", {
115
+ connect: async (xConnectorId) => {
116
+ const connector = wagmiConfigRef.current.connectors.find((c) => c.id === xConnectorId);
117
+ if (!connector) {
118
+ console.warn(
119
+ `[EvmActions] connect: connector "${xConnectorId}" not found in wagmi config`,
120
+ wagmiConfigRef.current.connectors.map((c) => c.id)
121
+ );
122
+ return void 0;
1370
123
  }
1371
- return void 0;
1372
- case "SOLANA":
1373
- if (solanaWallet.connected) {
1374
- return {
1375
- xAccount: { address: solanaWallet.publicKey?.toString(), xChainType },
1376
- xConnectorId: `${solanaWallet.wallet?.adapter.name}`
1377
- };
124
+ useXWalletStore.getState().clearUserDisconnected("EVM");
125
+ try {
126
+ await connectRef.current({ connector });
127
+ } catch (error) {
128
+ if (error instanceof Error && error.name === "ConnectorAlreadyConnectedError") {
129
+ return void 0;
130
+ }
131
+ throw error;
1378
132
  }
1379
133
  return void 0;
1380
- default:
1381
- return xConnection;
1382
- }
1383
- }, [xChainType, xConnection, evmAddress, suiAccount, evmConnections, suiCurrentWallet, solanaWallet]);
1384
- return xConnection2;
1385
- }
1386
-
1387
- // src/hooks/useXAccount.ts
1388
- function isChainType(chainIdentifier) {
1389
- return ChainTypeArr.includes(chainIdentifier);
1390
- }
1391
- function useXAccount(chainIdentifier) {
1392
- const resolvedChainType = chainIdentifier ? isChainType(chainIdentifier) ? chainIdentifier : getXChainType(chainIdentifier) : void 0;
1393
- const xConnection = useXConnection(resolvedChainType);
1394
- const xAccount = useMemo(() => {
1395
- if (!resolvedChainType) {
1396
- return {
1397
- address: void 0,
1398
- xChainType: void 0
1399
- };
1400
- }
1401
- return xConnection?.xAccount || { address: void 0, xChainType: resolvedChainType };
1402
- }, [resolvedChainType, xConnection]);
1403
- return xAccount;
1404
- }
1405
- function useXAccounts() {
1406
- const xChainTypes = useXWagmiStore((state) => Object.keys(state.xServices));
1407
- const xConnections = useXWagmiStore((state) => state.xConnections);
1408
- const { address: evmAddress } = useAccount();
1409
- const suiAccount = useCurrentAccount();
1410
- const solanaWallet = useWallet();
1411
- const xAccounts = useMemo(() => {
1412
- const result = {};
1413
- for (const xChainType of xChainTypes) {
1414
- const xConnection = xConnections[xChainType];
1415
- if (xConnection?.xAccount) {
1416
- result[xChainType] = xConnection.xAccount;
1417
- } else {
1418
- result[xChainType] = {
1419
- address: void 0,
1420
- xChainType
1421
- };
1422
- }
1423
- }
1424
- if (evmAddress) {
1425
- result["EVM"] = {
1426
- address: evmAddress,
1427
- xChainType: "EVM"
1428
- };
1429
- }
1430
- if (suiAccount) {
1431
- result["SUI"] = {
1432
- address: suiAccount.address,
1433
- xChainType: "SUI"
1434
- };
1435
- }
1436
- if (solanaWallet.publicKey) {
1437
- result["SOLANA"] = {
1438
- address: solanaWallet.publicKey.toString(),
1439
- xChainType: "SOLANA"
1440
- };
1441
- }
1442
- return result;
1443
- }, [xChainTypes, xConnections, evmAddress, suiAccount, solanaWallet]);
1444
- return xAccounts;
1445
- }
1446
- function useXConnect() {
1447
- const setXConnection = useXWagmiStore((state) => state.setXConnection);
1448
- const { connectAsync: evmConnectAsync } = useConnect();
1449
- const { mutateAsync: suiConnectAsync } = useConnectWallet();
1450
- const { select, connect } = useWallet();
1451
- return useMutation({
1452
- mutationFn: async (xConnector) => {
1453
- const xChainType = xConnector.xChainType;
1454
- let xAccount;
1455
- switch (xChainType) {
1456
- case "EVM":
1457
- await evmConnectAsync({ connector: xConnector.connector });
1458
- break;
1459
- case "SUI":
1460
- await suiConnectAsync({ wallet: xConnector.wallet });
1461
- break;
1462
- case "SOLANA": {
1463
- const walletName = xConnector.wallet.adapter.name;
1464
- select(walletName);
1465
- const adapter = xConnector.wallet.adapter;
1466
- if (!adapter) throw new Error("No adapter found for Solana wallet");
1467
- if (walletName === "MetaMask") {
1468
- await new Promise((resolve, reject) => {
1469
- const timeout = setTimeout(() => {
1470
- cleanup();
1471
- reject(new Error("Wallet connection timeout"));
1472
- }, 3e4);
1473
- const handleConnect = () => {
1474
- cleanup();
1475
- resolve();
1476
- };
1477
- const handleError = (error) => {
1478
- cleanup();
1479
- reject(error);
1480
- };
1481
- const cleanup = () => {
1482
- clearTimeout(timeout);
1483
- adapter.off("connect", handleConnect);
1484
- adapter.off("error", handleError);
1485
- };
1486
- adapter.on("connect", handleConnect);
1487
- adapter.on("error", handleError);
1488
- connect().catch((err) => {
1489
- cleanup();
1490
- reject(err);
1491
- });
1492
- });
1493
- }
1494
- break;
134
+ },
135
+ disconnect: async () => {
136
+ const store = useXWalletStore.getState();
137
+ store.unsetXConnection("EVM");
138
+ store.markUserDisconnected("EVM");
139
+ try {
140
+ await disconnectRef.current();
141
+ } catch (error) {
142
+ console.warn("[EvmActions] wagmi disconnect failed (zustand already cleared):", error);
1495
143
  }
1496
- default:
1497
- xAccount = await xConnector.connect();
1498
- break;
1499
- }
1500
- if (xAccount) {
1501
- setXConnection(xConnector.xChainType, {
1502
- xAccount,
1503
- xConnectorId: xConnector.id
1504
- });
1505
- }
1506
- return xAccount;
1507
- }
1508
- });
1509
- }
1510
-
1511
- // src/xchains/solana/SolanaXConnector.ts
1512
- var SolanaXConnector = class extends XConnector {
1513
- constructor(wallet) {
1514
- super("SOLANA", wallet?.adapter.name, wallet?.adapter.name);
1515
- this.wallet = wallet;
1516
- }
1517
- getXService() {
1518
- return SolanaXService.getInstance();
1519
- }
1520
- async connect() {
1521
- return;
1522
- }
1523
- async disconnect() {
1524
- }
1525
- get icon() {
1526
- return this.wallet?.adapter.icon;
1527
- }
1528
- };
1529
- var useStellarXConnectors = () => {
1530
- const xService = useXService("STELLAR");
1531
- return useQuery({
1532
- queryKey: ["stellar-wallets", xService],
1533
- queryFn: async () => {
1534
- if (!xService) {
1535
- return [];
144
+ },
145
+ getConnectors: () => useXWalletStore.getState().xConnectorsByChain.EVM ?? [],
146
+ getConnection: () => useXWalletStore.getState().xConnections.EVM,
147
+ signMessage: async (message) => {
148
+ const signature = await signMessageRef.current({ message });
149
+ return signature;
1536
150
  }
1537
- const wallets = await xService.walletsKit.getSupportedWallets();
1538
- return wallets.filter((wallet) => wallet.isAvailable).map((wallet) => new StellarWalletsKitXConnector(wallet));
1539
- }
1540
- });
151
+ });
152
+ }, [registerChainActions]);
153
+ return null;
1541
154
  };
1542
-
1543
- // src/hooks/useXService.ts
1544
- function useXService(xChainType) {
1545
- const xService = useXWagmiStore((state) => xChainType ? state.xServices[xChainType] : void 0);
1546
- return xService;
1547
- }
1548
-
1549
- // src/xchains/near/NearXConnector.ts
1550
- var NearXConnector = class extends XConnector {
1551
- constructor(wallet) {
1552
- super("NEAR", wallet.manifest.name, wallet.manifest.id);
1553
- this._wallet = wallet;
1554
- }
1555
- getXService() {
1556
- return NearXService.getInstance();
1557
- }
1558
- async connect() {
1559
- const walletSelector = this.getXService().walletSelector;
1560
- const wallet = await walletSelector.connect({ walletId: this._wallet.manifest.id });
1561
- const accounts = await wallet.getAccounts();
1562
- if (accounts.length === 0 || accounts[0] === void 0) {
1563
- return void 0;
1564
- }
1565
- return {
1566
- address: accounts[0].accountId,
1567
- xChainType: this.xChainType
1568
- };
1569
- }
1570
- async disconnect() {
1571
- const walletSelector = this.getXService().walletSelector;
1572
- await walletSelector.disconnect(this._wallet);
1573
- }
1574
- get icon() {
1575
- return this._wallet.manifest.icon;
155
+ var EvmProvider = ({ children, config }) => {
156
+ const reconnectOnMount = config.reconnectOnMount ?? EVM_DEFAULT_RECONNECT_ON_MOUNT;
157
+ const ssr = config.ssr ?? EVM_DEFAULT_SSR;
158
+ const queryClientRef = useRef(null);
159
+ if (!queryClientRef.current) {
160
+ queryClientRef.current = new QueryClient();
1576
161
  }
1577
- };
1578
-
1579
- // src/xchains/near/useNearXConnectors.ts
1580
- var useNearXConnectors = () => {
1581
- const xService = useXService("NEAR");
1582
- return useQuery({
1583
- queryKey: ["near-wallets"],
1584
- queryFn: async () => {
1585
- if (!xService) {
1586
- return [];
162
+ const walletConnectConfig = config.walletConnect;
163
+ const wagmiConfig = useMemo(() => {
164
+ const connectors = [];
165
+ if (walletConnectConfig) {
166
+ if (walletConnectConfig.projectId) {
167
+ connectors.push(walletConnect({ showQrModal: true, ...walletConnectConfig }));
168
+ } else {
169
+ console.warn("[wallet-sdk-react] walletConnect.projectId is required \u2014 WalletConnect connector skipped.");
1587
170
  }
1588
- await xService.walletSelector.whenManifestLoaded;
1589
- const wallets = xService.walletSelector.availableWallets;
1590
- return wallets.map((wallet) => new NearXConnector(wallet));
1591
171
  }
1592
- });
172
+ return createWagmiConfig(config.chains, { reconnectOnMount, ssr, connectors });
173
+ }, [config.chains, reconnectOnMount, ssr, walletConnectConfig]);
174
+ return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClientRef.current, children: /* @__PURE__ */ jsxs(WagmiProvider, { reconnectOnMount, config: wagmiConfig, initialState: config.initialState, children: [
175
+ /* @__PURE__ */ jsx(EvmHydrator, {}),
176
+ /* @__PURE__ */ jsx(EvmActions, {}),
177
+ children
178
+ ] }) });
1593
179
  };
1594
-
1595
- // src/hooks/useXConnectors.ts
1596
- function useXConnectors(xChainType) {
1597
- const xService = useXService(xChainType);
1598
- const evmConnectors = useConnectors();
1599
- const suiWallets = useWallets();
1600
- const { data: stellarXConnectors } = useStellarXConnectors();
1601
- const { data: nearXConnectors } = useNearXConnectors();
1602
- const stacksXConnectors = useStacksXConnectors();
1603
- const { wallets: solanaWallets } = useWallet();
1604
- const xConnectors = useMemo(() => {
1605
- if (!xChainType || !xService) {
1606
- return [];
1607
- }
1608
- switch (xChainType) {
1609
- case "EVM":
1610
- return evmConnectors.map((connector) => new EvmXConnector(connector));
1611
- case "SUI":
1612
- return suiWallets.map((wallet) => new SuiXConnector(wallet));
1613
- case "STELLAR":
1614
- return stellarXConnectors || [];
1615
- case "SOLANA":
1616
- return solanaWallets.filter((wallet) => wallet.readyState === "Installed").map((wallet) => new SolanaXConnector(wallet));
1617
- case "NEAR":
1618
- return nearXConnectors || [];
1619
- case "STACKS":
1620
- return stacksXConnectors;
1621
- default:
1622
- return xService.getXConnectors();
1623
- }
1624
- }, [
1625
- xService,
1626
- xChainType,
1627
- evmConnectors,
1628
- suiWallets,
1629
- stellarXConnectors,
1630
- solanaWallets,
1631
- nearXConnectors,
1632
- stacksXConnectors
1633
- ]);
1634
- return xConnectors;
1635
- }
1636
- function useXDisconnect() {
1637
- const xConnections = useXWagmiStore((state) => state.xConnections);
1638
- const unsetXConnection = useXWagmiStore((state) => state.unsetXConnection);
1639
- const { disconnectAsync } = useDisconnect();
1640
- const { mutateAsync: suiDisconnectAsync } = useDisconnectWallet();
180
+ var SolanaHydrator = () => {
181
+ const { connection } = useConnection();
1641
182
  const solanaWallet = useWallet();
1642
- return useCallback(
1643
- async (xChainType) => {
1644
- switch (xChainType) {
1645
- case "EVM":
1646
- await disconnectAsync();
1647
- break;
1648
- case "SUI":
1649
- await suiDisconnectAsync();
1650
- break;
1651
- case "SOLANA":
1652
- await solanaWallet.disconnect();
1653
- break;
1654
- case "NEAR": {
1655
- const nearXService = getXService("NEAR");
1656
- nearXService.walletSelector.disconnect();
1657
- break;
1658
- }
1659
- default: {
1660
- const xService = getXService(xChainType);
1661
- const xConnectorId = xConnections[xChainType]?.xConnectorId;
1662
- const xConnector = xConnectorId ? xService.getXConnectorById(xConnectorId) : void 0;
1663
- await xConnector?.disconnect();
1664
- break;
1665
- }
1666
- }
1667
- unsetXConnection(xChainType);
1668
- },
1669
- [xConnections, unsetXConnection, disconnectAsync, suiDisconnectAsync, solanaWallet]
183
+ const setXConnection = useXWalletStore((state) => state.setXConnection);
184
+ const unsetXConnection = useXWalletStore((state) => state.unsetXConnection);
185
+ const setWalletProvider = useXWalletStore((state) => state.setWalletProvider);
186
+ const walletConfig = useWalletConfig();
187
+ const solanaDefaults = getEntryDefaults(
188
+ walletConfig.SOLANA?.chains?.[ChainKeys.SOLANA_MAINNET]
1670
189
  );
1671
- }
1672
- function useXBalances({
1673
- xChainId,
1674
- xTokens,
1675
- address
1676
- }) {
1677
- const xService = useXService(getXChainType(xChainId));
1678
- return useQuery({
1679
- queryKey: ["xBalances", xChainId, xTokens.map((x) => x.symbol), address],
1680
- queryFn: async () => {
1681
- if (!xService) {
1682
- return {};
1683
- }
1684
- const balances = await xService.getBalances(address, xTokens);
1685
- return balances;
1686
- },
1687
- enabled: !!xService && !!address && (xTokens?.length ?? 0) > 0,
1688
- refetchInterval: 5e3
1689
- });
1690
- }
1691
- function useEthereumChainId() {
1692
- const injectiveXService = useXService("INJECTIVE");
1693
- const [ethereumChainId, setEthereumChainId] = React2.useState(null);
1694
190
  useEffect(() => {
1695
- if (!injectiveXService?.walletStrategy?.getWallet()) return;
1696
- const walletStrategy = injectiveXService.walletStrategy;
1697
- if (walletStrategy.getWallet() !== Wallet.Metamask) return;
1698
- const getEthereumChainId = async () => {
1699
- try {
1700
- const chainId = await walletStrategy.getEthereumChainId();
1701
- setEthereumChainId(Number.parseInt(chainId));
1702
- } catch (e) {
1703
- console.warn("Failed to get Ethereum chain ID:", e);
1704
- }
1705
- };
1706
- getEthereumChainId();
1707
- try {
1708
- walletStrategy.getStrategy().onChainIdChanged(getEthereumChainId);
1709
- } catch (e) {
1710
- console.warn("Failed to subscribe to chain ID changes:", e);
1711
- }
1712
- }, [injectiveXService?.walletStrategy]);
1713
- return ethereumChainId;
1714
- }
1715
- var switchEthereumChain = async () => {
1716
- const metamaskProvider = window.ethereum;
1717
- return await Promise.race([
1718
- metamaskProvider.request({
1719
- method: "wallet_switchEthereumChain",
1720
- params: [{ chainId: "0x1" }]
1721
- }),
1722
- new Promise(
1723
- (resolve) => metamaskProvider.on("change", ({ chain }) => {
1724
- if (chain?.id === 1) {
1725
- resolve();
1726
- }
1727
- })
1728
- )
1729
- ]);
1730
- };
1731
- var useEvmSwitchChain = (expectedXChainId) => {
1732
- const xChainType = getXChainType(expectedXChainId);
1733
- const expectedChainId = baseChainInfo[expectedXChainId].chainId;
1734
- const injectiveXService = useXService("INJECTIVE");
1735
- const ethereumChainId = useEthereumChainId();
1736
- const { chainId } = useAccount();
1737
- const isWrongChain = useMemo(() => {
1738
- return xChainType === "EVM" && chainId !== expectedChainId || xChainType === "INJECTIVE" && injectiveXService && injectiveXService.walletStrategy.getWallet() === Wallet.Metamask && ethereumChainId !== mainnet$1.id;
1739
- }, [xChainType, chainId, expectedChainId, ethereumChainId, injectiveXService]);
1740
- const { switchChain } = useSwitchChain();
1741
- const handleSwitchChain = useCallback(() => {
1742
- if (xChainType === "INJECTIVE") {
1743
- switchEthereumChain();
1744
- } else {
1745
- switchChain({ chainId: expectedChainId });
191
+ if (connection) {
192
+ SolanaXService.getInstance().connection = connection;
1746
193
  }
1747
- }, [switchChain, expectedChainId, xChainType]);
1748
- return useMemo(
1749
- () => ({
1750
- isWrongChain,
1751
- handleSwitchChain
1752
- }),
1753
- [isWrongChain, handleSwitchChain]
194
+ }, [connection]);
195
+ const solanaWalletRef = useRef(solanaWallet);
196
+ useEffect(() => {
197
+ solanaWalletRef.current = solanaWallet;
198
+ });
199
+ const solanaConnectors = useMemo(
200
+ () => solanaWallet.wallets.filter((wallet) => wallet.readyState === "Installed").map((wallet) => new SolanaXConnector(wallet)),
201
+ [solanaWallet.wallets]
1754
202
  );
203
+ useEffect(() => {
204
+ SolanaXService.getInstance().setXConnectors(solanaConnectors);
205
+ useXWalletStore.getState().setXConnectors("SOLANA", solanaConnectors);
206
+ }, [solanaConnectors]);
207
+ const wasConnectedRef = useRef(!!useXWalletStore.getState().xConnections.SOLANA);
208
+ useEffect(() => {
209
+ if (solanaWallet.connected && solanaWallet.publicKey) {
210
+ wasConnectedRef.current = true;
211
+ setXConnection("SOLANA", {
212
+ xAccount: { address: solanaWallet.publicKey.toString(), xChainType: "SOLANA" },
213
+ xConnectorId: `${solanaWallet.wallet?.adapter.name}`
214
+ });
215
+ } else if (wasConnectedRef.current) {
216
+ wasConnectedRef.current = false;
217
+ unsetXConnection("SOLANA");
218
+ }
219
+ }, [solanaWallet.connected, solanaWallet.publicKey, solanaWallet.wallet, setXConnection, unsetXConnection]);
220
+ const walletProvider = useMemo(() => {
221
+ if (solanaWallet.connected && solanaWallet.publicKey && solanaWallet.wallet && connection) {
222
+ return new SolanaWalletProvider({
223
+ wallet: solanaWallet,
224
+ endpoint: connection.rpcEndpoint,
225
+ defaults: solanaDefaults
226
+ });
227
+ }
228
+ return void 0;
229
+ }, [solanaWallet.connected, solanaWallet.publicKey, solanaWallet.wallet, connection, solanaDefaults]);
230
+ useEffect(() => {
231
+ SolanaXService.getInstance().wallet = solanaWalletRef.current;
232
+ setWalletProvider("SOLANA", walletProvider);
233
+ }, [walletProvider, setWalletProvider]);
234
+ return null;
1755
235
  };
1756
- function useWalletProvider(spokeChainId) {
1757
- const xChainType = getXChainType(spokeChainId);
1758
- const evmPublicClient = usePublicClient();
1759
- const { data: evmWalletClient } = useWalletClient();
1760
- const xService = useXService(getXChainType(spokeChainId));
1761
- const xAccount = useXAccount(spokeChainId);
1762
- const stacksConnection = useXConnection("STACKS");
1763
- const stacksConnectors = useXConnectors("STACKS");
1764
- const xConnection = useXConnection(xChainType);
1765
- return useMemo(() => {
1766
- switch (xChainType) {
1767
- case "EVM": {
1768
- if (!evmWalletClient) {
1769
- return void 0;
1770
- }
1771
- if (!evmPublicClient) {
1772
- return void 0;
1773
- }
1774
- return new EvmWalletProvider({
1775
- walletClient: evmWalletClient,
1776
- publicClient: evmPublicClient
1777
- });
1778
- }
1779
- case "SUI": {
1780
- const suiXService = xService;
1781
- const { client, wallet, account } = {
1782
- client: suiXService.suiClient,
1783
- wallet: suiXService.suiWallet,
1784
- account: suiXService.suiAccount
1785
- };
1786
- return new SuiWalletProvider({ client, wallet, account });
1787
- }
1788
- case "ICON": {
1789
- const { walletAddress, rpcUrl } = {
1790
- walletAddress: xAccount.address,
1791
- rpcUrl: CHAIN_INFO[1 /* MAINNET */].APIEndpoint
1792
- };
1793
- return new IconWalletProvider({
1794
- walletAddress,
1795
- rpcUrl
1796
- });
1797
- }
1798
- case "INJECTIVE": {
1799
- const injectiveXService = xService;
1800
- if (!injectiveXService) {
1801
- return void 0;
1802
- }
1803
- return new InjectiveWalletProvider({
1804
- msgBroadcaster: injectiveXService.msgBroadcaster
1805
- });
1806
- }
1807
- case "STELLAR": {
1808
- const stellarXService = xService;
1809
- if (!stellarXService.walletsKit) {
1810
- return void 0;
1811
- }
1812
- return new StellarWalletProvider({
1813
- type: "BROWSER_EXTENSION",
1814
- walletsKit: stellarXService.walletsKit,
1815
- network: "PUBLIC"
1816
- });
1817
- }
1818
- case "SOLANA": {
1819
- const solanaXService = xService;
1820
- if (!solanaXService.wallet) {
236
+ var SolanaActions = () => {
237
+ const solanaWallet = useWallet();
238
+ const registerChainActions = useXWalletStore((state) => state.registerChainActions);
239
+ const walletRef = useRef(solanaWallet);
240
+ useEffect(() => {
241
+ walletRef.current = solanaWallet;
242
+ }, [solanaWallet]);
243
+ useEffect(() => {
244
+ registerChainActions("SOLANA", {
245
+ connect: async (xConnectorId) => {
246
+ const wallet = walletRef.current.wallets.find((w) => w.adapter.name === xConnectorId);
247
+ if (!wallet) {
248
+ console.warn(
249
+ `[SolanaActions] connect: wallet "${xConnectorId}" not found in adapter list`,
250
+ walletRef.current.wallets.map((w) => w.adapter.name)
251
+ );
1821
252
  return void 0;
1822
253
  }
1823
- if (!solanaXService.connection) {
254
+ walletRef.current.select(wallet.adapter.name);
255
+ if (wallet.adapter.connected) {
1824
256
  return void 0;
1825
257
  }
1826
- return new SolanaWalletProvider({
1827
- wallet: solanaXService.wallet,
1828
- endpoint: solanaXService.connection.rpcEndpoint
258
+ await new Promise((resolve, reject) => {
259
+ const timeout = setTimeout(() => {
260
+ cleanup();
261
+ reject(new Error("Wallet connection timeout"));
262
+ }, SOLANA_METAMASK_CONNECT_TIMEOUT_MS);
263
+ const onConnect = () => {
264
+ cleanup();
265
+ resolve();
266
+ };
267
+ const onError = (err) => {
268
+ cleanup();
269
+ reject(err);
270
+ };
271
+ const cleanup = () => {
272
+ clearTimeout(timeout);
273
+ wallet.adapter.off("connect", onConnect);
274
+ wallet.adapter.off("error", onError);
275
+ };
276
+ wallet.adapter.on("connect", onConnect);
277
+ wallet.adapter.on("error", onError);
278
+ setTimeout(() => {
279
+ if (!wallet.adapter.connected && !wallet.adapter.connecting) {
280
+ walletRef.current.connect().catch((err) => {
281
+ cleanup();
282
+ reject(err);
283
+ });
284
+ }
285
+ }, 0);
1829
286
  });
1830
- }
1831
- case "BITCOIN": {
1832
- if (!xConnection?.xConnectorId) return void 0;
1833
- const connector = BitcoinXService.getInstance().getXConnectorById(xConnection.xConnectorId);
1834
- if (!connector) return void 0;
1835
- return connector.recreateWalletProvider(xConnection.xAccount);
1836
- }
1837
- case "NEAR": {
1838
- const nearXService = xService;
1839
- if (!nearXService.walletSelector) {
1840
- return void 0;
1841
- }
1842
- return new NearWalletProvider({ wallet: nearXService.walletSelector });
1843
- }
1844
- case "STACKS": {
1845
- const address = xAccount.address;
1846
- if (!address) {
1847
- return void 0;
1848
- }
1849
- const activeStacksConnector = stacksConnectors.find((c) => c.id === stacksConnection?.xConnectorId);
1850
- return new StacksWalletProvider({ address, provider: activeStacksConnector?.getProvider() });
1851
- }
1852
- default:
1853
287
  return void 0;
1854
- }
1855
- }, [
1856
- xChainType,
1857
- evmPublicClient,
1858
- evmWalletClient,
1859
- xService,
1860
- xAccount,
1861
- stacksConnection,
1862
- stacksConnectors,
1863
- xConnection
1864
- ]);
1865
- }
1866
- function useXSignMessage() {
1867
- const { signMessage } = useWallet();
1868
- const { signMessageAsync: evmSignMessage } = useSignMessage();
1869
- const { mutateAsync: signPersonalMessage } = useSignPersonalMessage();
1870
- const { address: injectiveAddress } = useXAccount("INJECTIVE");
1871
- return useMutation({
1872
- mutationFn: async ({ xChainType, message }) => {
1873
- let signature;
1874
- switch (xChainType) {
1875
- case "EVM": {
1876
- signature = await evmSignMessage({ message });
1877
- break;
1878
- }
1879
- case "SUI": {
1880
- const res = await signPersonalMessage({ message: new Uint8Array(new TextEncoder().encode(message)) });
1881
- signature = res.signature;
1882
- break;
1883
- }
1884
- case "SOLANA": {
1885
- if (!signMessage) {
1886
- throw new Error("Solana wallet not connected");
1887
- }
1888
- signature = await signMessage(new TextEncoder().encode(message));
1889
- break;
1890
- }
1891
- case "STELLAR": {
1892
- const res = await StellarXService.getInstance().walletsKit.signMessage(message);
1893
- signature = res.signedMessage;
1894
- break;
1895
- }
1896
- case "INJECTIVE": {
1897
- if (!injectiveAddress) {
1898
- throw new Error("Injective address not found");
1899
- }
1900
- const ethereumAddress = getEthereumAddress(injectiveAddress);
1901
- const walletStrategy = InjectiveXService.getInstance().walletStrategy;
1902
- const res = await walletStrategy.signArbitrary(
1903
- walletStrategy.getWallet() === Wallet.Metamask ? ethereumAddress : injectiveAddress,
1904
- message
1905
- );
1906
- if (!res) {
1907
- throw new Error("Injective signature not found");
1908
- }
1909
- signature = res;
1910
- break;
288
+ },
289
+ disconnect: async () => {
290
+ await walletRef.current.disconnect();
291
+ },
292
+ getConnectors: () => useXWalletStore.getState().xConnectorsByChain.SOLANA ?? [],
293
+ getConnection: () => useXWalletStore.getState().xConnections.SOLANA,
294
+ signMessage: async (message) => {
295
+ if (!walletRef.current.signMessage) {
296
+ throw new Error("Solana wallet not connected");
1911
297
  }
1912
- default:
1913
- console.warn("Unsupported chain type");
1914
- break;
298
+ const signature = await walletRef.current.signMessage(new TextEncoder().encode(message));
299
+ return Buffer.from(signature).toString("base64");
1915
300
  }
1916
- return signature;
1917
- }
1918
- });
1919
- }
1920
-
1921
- // src/xchains/bitcoin/useBitcoinXConnectors.ts
1922
- function useBitcoinXConnectors() {
1923
- const xService = useXService("BITCOIN");
1924
- return useMemo(() => {
1925
- return xService?.getXConnectors() || [];
1926
- }, [xService]);
1927
- }
1928
- var Hydrate = ({ rpcConfig }) => {
301
+ });
302
+ }, [registerChainActions]);
303
+ return null;
304
+ };
305
+ var emptyWallets = [];
306
+ var SolanaProvider = ({ children, config }) => {
307
+ const autoConnect = config.autoConnect ?? SOLANA_DEFAULT_AUTO_CONNECT;
308
+ const endpoint = config.chains?.[ChainKeys.SOLANA_MAINNET]?.rpcUrl ?? SOLANA_DEFAULT_RPC_URL;
309
+ return /* @__PURE__ */ jsx(ConnectionProvider, { endpoint, children: /* @__PURE__ */ jsxs(WalletProvider, { wallets: emptyWallets, autoConnect, children: [
310
+ /* @__PURE__ */ jsx(SolanaHydrator, {}),
311
+ /* @__PURE__ */ jsx(SolanaActions, {}),
312
+ children
313
+ ] }) });
314
+ };
315
+ var SuiHydrator = () => {
1929
316
  const suiClient = useSuiClient();
317
+ const { currentWallet } = useCurrentWallet();
318
+ const suiAccount = useCurrentAccount();
319
+ const suiWallets = useWallets();
320
+ const setXConnection = useXWalletStore((state) => state.setXConnection);
321
+ const unsetXConnection = useXWalletStore((state) => state.unsetXConnection);
322
+ const setWalletProvider = useXWalletStore((state) => state.setWalletProvider);
323
+ const walletConfig = useWalletConfig();
324
+ const suiDefaults = getEntryDefaults(walletConfig.SUI?.chains?.[ChainKeys.SUI_MAINNET]);
1930
325
  useEffect(() => {
1931
- if (suiClient) {
1932
- SuiXService.getInstance().suiClient = suiClient;
1933
- }
1934
- }, [suiClient]);
1935
- const { currentWallet: suiWallet } = useCurrentWallet();
326
+ const service = SuiXService.getInstance();
327
+ if (suiClient) service.suiClient = suiClient;
328
+ if (currentWallet) service.suiWallet = currentWallet;
329
+ if (suiAccount) service.suiAccount = suiAccount;
330
+ }, [suiClient, currentWallet, suiAccount]);
331
+ const suiConnectors = useMemo(() => suiWallets.map((wallet) => new SuiXConnector(wallet)), [suiWallets]);
1936
332
  useEffect(() => {
1937
- if (suiWallet) {
1938
- SuiXService.getInstance().suiWallet = suiWallet;
1939
- }
1940
- }, [suiWallet]);
1941
- const suiAccount = useCurrentAccount();
333
+ SuiXService.getInstance().setXConnectors(suiConnectors);
334
+ useXWalletStore.getState().setXConnectors("SUI", suiConnectors);
335
+ }, [suiConnectors]);
336
+ const wasConnectedRef = useRef(!!useXWalletStore.getState().xConnections.SUI);
1942
337
  useEffect(() => {
1943
- if (suiAccount) {
1944
- SuiXService.getInstance().suiAccount = suiAccount;
338
+ if (currentWallet && suiAccount?.address) {
339
+ wasConnectedRef.current = true;
340
+ setXConnection("SUI", {
341
+ xAccount: { address: suiAccount.address, xChainType: "SUI" },
342
+ // Match SuiXConnector.id derivation: prefer Wallet Standard `id`, fall back to `name`.
343
+ xConnectorId: currentWallet.id ?? currentWallet.name
344
+ });
345
+ } else if (wasConnectedRef.current) {
346
+ wasConnectedRef.current = false;
347
+ unsetXConnection("SUI");
348
+ }
349
+ }, [currentWallet, suiAccount, setXConnection, unsetXConnection]);
350
+ const walletProvider = useMemo(() => {
351
+ if (suiClient && currentWallet && suiAccount) {
352
+ assertSuiProviderShape("SuiHydrator", suiClient, currentWallet, suiAccount);
353
+ return new SuiWalletProvider({
354
+ client: suiClient,
355
+ wallet: currentWallet,
356
+ account: suiAccount,
357
+ defaults: suiDefaults
358
+ });
1945
359
  }
1946
- }, [suiAccount]);
1947
- const { connection: solanaConnection } = useConnection();
1948
- const solanaWallet = useWallet();
360
+ return void 0;
361
+ }, [suiClient, currentWallet, suiAccount, suiDefaults]);
1949
362
  useEffect(() => {
1950
- if (solanaConnection) {
1951
- SolanaXService.getInstance().connection = solanaConnection;
1952
- }
1953
- }, [solanaConnection]);
363
+ setWalletProvider("SUI", walletProvider);
364
+ }, [walletProvider, setWalletProvider]);
365
+ return null;
366
+ };
367
+ var SuiActions = () => {
368
+ const suiWallets = useWallets();
369
+ const { mutateAsync: suiConnectAsync } = useConnectWallet();
370
+ const { mutateAsync: suiDisconnectAsync } = useDisconnectWallet();
371
+ const { mutateAsync: signPersonalMessage } = useSignPersonalMessage();
372
+ const registerChainActions = useXWalletStore((state) => state.registerChainActions);
373
+ const connectRef = useRef(suiConnectAsync);
374
+ const disconnectRef = useRef(suiDisconnectAsync);
375
+ const signMessageRef = useRef(signPersonalMessage);
376
+ const walletsRef = useRef(suiWallets);
1954
377
  useEffect(() => {
1955
- if (solanaWallet) {
1956
- SolanaXService.getInstance().wallet = solanaWallet;
1957
- }
1958
- }, [solanaWallet]);
1959
- const wagmiConfig = useConfig();
378
+ connectRef.current = suiConnectAsync;
379
+ }, [suiConnectAsync]);
1960
380
  useEffect(() => {
1961
- if (wagmiConfig) {
1962
- EvmXService.getInstance().wagmiConfig = wagmiConfig;
1963
- }
1964
- }, [wagmiConfig]);
381
+ disconnectRef.current = suiDisconnectAsync;
382
+ }, [suiDisconnectAsync]);
1965
383
  useEffect(() => {
1966
- StacksXService.getInstance().network = createNetwork({
1967
- network: "mainnet",
1968
- client: { baseUrl: rpcConfig.stacks ?? "https://api.mainnet.hiro.so" }
384
+ signMessageRef.current = signPersonalMessage;
385
+ }, [signPersonalMessage]);
386
+ useEffect(() => {
387
+ walletsRef.current = suiWallets;
388
+ }, [suiWallets]);
389
+ useEffect(() => {
390
+ registerChainActions("SUI", {
391
+ connect: async (xConnectorId) => {
392
+ const wallet = walletsRef.current.find((w) => (w.id ?? w.name) === xConnectorId);
393
+ if (!wallet) {
394
+ console.warn(
395
+ `[SuiActions] connect: wallet "${xConnectorId}" not found in adapter list`,
396
+ walletsRef.current.map((w) => w.name)
397
+ );
398
+ return void 0;
399
+ }
400
+ await connectRef.current({ wallet });
401
+ return void 0;
402
+ },
403
+ disconnect: async () => {
404
+ await disconnectRef.current();
405
+ },
406
+ getConnectors: () => useXWalletStore.getState().xConnectorsByChain.SUI ?? [],
407
+ getConnection: () => useXWalletStore.getState().xConnections.SUI,
408
+ signMessage: async (message) => {
409
+ const res = await signMessageRef.current({ message: new Uint8Array(new TextEncoder().encode(message)) });
410
+ return res.signature;
411
+ }
1969
412
  });
1970
- }, [rpcConfig.stacks]);
413
+ }, [registerChainActions]);
1971
414
  return null;
1972
415
  };
416
+ var SuiProvider = ({ children, config }) => {
417
+ const autoConnect = config.autoConnect ?? SUI_DEFAULT_AUTO_CONNECT;
418
+ const network = config.network ?? SUI_DEFAULT_NETWORK;
419
+ const rpcUrl = config.chains?.[ChainKeys.SUI_MAINNET]?.rpcUrl ?? getFullnodeUrl(network);
420
+ return /* @__PURE__ */ jsx(SuiClientProvider, { networks: { [network]: { url: rpcUrl } }, defaultNetwork: network, children: /* @__PURE__ */ jsxs(WalletProvider$1, { autoConnect, children: [
421
+ /* @__PURE__ */ jsx(SuiHydrator, {}),
422
+ /* @__PURE__ */ jsx(SuiActions, {}),
423
+ children
424
+ ] }) });
425
+ };
1973
426
 
1974
427
  // src/xchains/icon/actions.ts
1975
428
  var reconnectIcon = async () => {
1976
- const iconConnection = useXWagmiStore.getState().xConnections.ICON;
429
+ const iconConnection = useXWalletStore.getState().xConnections.ICON;
1977
430
  if (!iconConnection) return;
1978
431
  const recentXConnectorId = iconConnection.xConnectorId;
1979
432
  const detail = await request({
1980
433
  type: "REQUEST_ADDRESS" /* REQUEST_ADDRESS */
1981
434
  });
1982
435
  if (detail?.type === "RESPONSE_ADDRESS" /* RESPONSE_ADDRESS */) {
1983
- useXWagmiStore.setState({
1984
- xConnections: {
1985
- ...useXWagmiStore.getState().xConnections,
1986
- ICON: {
1987
- xAccount: {
1988
- address: detail?.payload,
1989
- xChainType: "ICON"
1990
- },
1991
- xConnectorId: recentXConnectorId
1992
- }
1993
- }
436
+ useXWalletStore.getState().setXConnection("ICON", {
437
+ xAccount: {
438
+ address: detail?.payload,
439
+ xChainType: "ICON"
440
+ },
441
+ xConnectorId: recentXConnectorId
1994
442
  });
1995
443
  }
1996
444
  };
445
+ function isWallet(value) {
446
+ return Object.values(Wallet).some((v) => v === value);
447
+ }
1997
448
  var reconnectInjective = async () => {
1998
- const injectiveConnection = useXWagmiStore.getState().xConnections.INJECTIVE;
449
+ const injectiveConnection = useXWalletStore.getState().xConnections.INJECTIVE;
1999
450
  if (!injectiveConnection) return;
2000
451
  const recentXConnectorId = injectiveConnection.xConnectorId;
452
+ if (!isWallet(recentXConnectorId)) {
453
+ console.warn(`[Injective] Stale wallet ID skipped: ${recentXConnectorId}`);
454
+ return;
455
+ }
2001
456
  const walletStrategy = InjectiveXService.getInstance().walletStrategy;
2002
457
  await walletStrategy.setWallet(recentXConnectorId);
2003
458
  const addresses = await walletStrategy.getAddresses();
2004
- const address = isEvmBrowserWallet(recentXConnectorId) ? getInjectiveAddress(addresses?.[0]) : addresses?.[0];
2005
- useXWagmiStore.setState({
2006
- xConnections: {
2007
- ...useXWagmiStore.getState().xConnections,
2008
- INJECTIVE: {
2009
- xAccount: {
2010
- address,
2011
- xChainType: "INJECTIVE"
2012
- },
2013
- xConnectorId: recentXConnectorId
2014
- }
2015
- }
459
+ const firstAddress = addresses?.[0];
460
+ if (!firstAddress) return;
461
+ const address = isEvmBrowserWallet(recentXConnectorId) ? getInjectiveAddress(firstAddress) : firstAddress;
462
+ useXWalletStore.getState().setXConnection("INJECTIVE", {
463
+ xAccount: {
464
+ address,
465
+ xChainType: "INJECTIVE"
466
+ },
467
+ xConnectorId: recentXConnectorId
2016
468
  });
2017
469
  };
2018
470
 
2019
471
  // src/xchains/stellar/actions.ts
2020
472
  var reconnectStellar = async () => {
2021
- const stellarConnection = useXWagmiStore.getState().xConnections.STELLAR;
473
+ const stellarConnection = useXWalletStore.getState().xConnections.STELLAR;
2022
474
  if (!stellarConnection) return;
2023
475
  const recentXConnectorId = stellarConnection.xConnectorId;
2024
476
  const stellarWalletKit = StellarXService.getInstance().walletsKit;
2025
477
  stellarWalletKit.setWallet(recentXConnectorId);
2026
478
  const { address } = await stellarWalletKit.getAddress();
2027
- useXWagmiStore.setState({
2028
- xConnections: {
2029
- ...useXWagmiStore.getState().xConnections,
2030
- STELLAR: {
2031
- xAccount: {
2032
- address,
2033
- xChainType: "STELLAR"
2034
- },
2035
- xConnectorId: recentXConnectorId
2036
- }
2037
- }
479
+ useXWalletStore.getState().setXConnection("STELLAR", {
480
+ xAccount: {
481
+ address,
482
+ xChainType: "STELLAR"
483
+ },
484
+ xConnectorId: recentXConnectorId
2038
485
  });
2039
486
  };
2040
- var queryClient = new QueryClient();
2041
- var defaultOptions = {
2042
- wagmi: {
2043
- reconnectOnMount: false,
2044
- ssr: true
2045
- },
2046
- solana: {
2047
- autoConnect: true
2048
- },
2049
- sui: {
2050
- autoConnect: true
487
+
488
+ // src/hooks/useInitChainServices.ts
489
+ function useInitChainServices(walletConfig) {
490
+ const initChainServices = useXWalletStore((state) => state.initChainServices);
491
+ const cleanupDisabledConnections = useXWalletStore((state) => state.cleanupDisabledConnections);
492
+ useEffect(() => {
493
+ initChainServices(walletConfig);
494
+ const afterHydration = () => {
495
+ cleanupDisabledConnections();
496
+ const store = useXWalletStore.getState();
497
+ for (const chainType of Object.keys(store.xConnections)) {
498
+ if (!chainRegistry[chainType]?.createWalletProvider) continue;
499
+ const conn = store.xConnections[chainType];
500
+ if (conn) store.setXConnection(chainType, conn);
501
+ }
502
+ if (walletConfig.ICON) {
503
+ reconnectIcon().catch((error) => console.warn("[wallet-sdk-react] ICON reconnect failed:", error));
504
+ }
505
+ if (walletConfig.INJECTIVE) {
506
+ reconnectInjective().catch((error) => console.warn("[wallet-sdk-react] Injective reconnect failed:", error));
507
+ }
508
+ if (walletConfig.STELLAR) {
509
+ reconnectStellar().catch((error) => console.warn("[wallet-sdk-react] Stellar reconnect failed:", error));
510
+ }
511
+ };
512
+ if (useXWalletStore.persist.hasHydrated()) {
513
+ afterHydration();
514
+ } else {
515
+ useXWalletStore.persist.onFinishHydration(afterHydration);
516
+ }
517
+ }, []);
518
+ }
519
+ var SodaxWalletProvider = ({ children, config }) => {
520
+ const configRef = useRef(config);
521
+ const frozen = configRef.current;
522
+ useInitChainServices(frozen);
523
+ let content = /* @__PURE__ */ jsx(Fragment, { children });
524
+ if (frozen.SOLANA) {
525
+ content = /* @__PURE__ */ jsx(SolanaProvider, { config: frozen.SOLANA, children: content });
2051
526
  }
527
+ if (frozen.SUI) {
528
+ content = /* @__PURE__ */ jsx(SuiProvider, { config: frozen.SUI, children: content });
529
+ }
530
+ if (frozen.EVM) {
531
+ content = /* @__PURE__ */ jsx(EvmProvider, { config: frozen.EVM, children: content });
532
+ }
533
+ return /* @__PURE__ */ jsx(WalletConfigProvider, { value: frozen, children: content });
2052
534
  };
2053
- var SodaxWalletProvider = ({ children, rpcConfig, options, initialState }) => {
2054
- const wagmi = useMemo(() => ({ ...defaultOptions.wagmi, ...options?.wagmi }), [options?.wagmi]);
2055
- const wagmiConfig = useMemo(() => {
2056
- return createWagmiConfig(rpcConfig, wagmi);
2057
- }, [rpcConfig, wagmi]);
2058
- const wallets = useMemo(() => [new UnsafeBurnerWalletAdapter()], []);
2059
- const solana = useMemo(() => ({ ...defaultOptions.solana, ...options?.solana }), [options?.solana]);
2060
- const sui = useMemo(() => ({ ...defaultOptions.sui, ...options?.sui }), [options?.sui]);
2061
- return /* @__PURE__ */ React2.createElement(QueryClientProvider, { client: queryClient }, /* @__PURE__ */ React2.createElement(WagmiProvider, { reconnectOnMount: wagmi.reconnectOnMount, config: wagmiConfig, initialState }, /* @__PURE__ */ React2.createElement(SuiClientProvider, { networks: { mainnet: { url: getFullnodeUrl("mainnet") } }, defaultNetwork: "mainnet" }, /* @__PURE__ */ React2.createElement(WalletProvider, { autoConnect: sui.autoConnect }, /* @__PURE__ */ React2.createElement(ConnectionProvider, { endpoint: rpcConfig["solana"] ?? "https://api.mainnet-beta.solana.com" }, /* @__PURE__ */ React2.createElement(WalletProvider$1, { wallets, autoConnect: solana.autoConnect }, /* @__PURE__ */ React2.createElement(Hydrate, { rpcConfig }), children))))));
2062
- };
2063
- reconnectIcon();
2064
- reconnectInjective();
2065
- reconnectStellar();
2066
-
2067
- // src/types/index.ts
2068
- var WalletId = /* @__PURE__ */ ((WalletId2) => {
2069
- WalletId2["METAMASK"] = "metamask";
2070
- WalletId2["HANA"] = "hana";
2071
- WalletId2["PHANTOM"] = "phantom";
2072
- WalletId2["SUI"] = "sui";
2073
- WalletId2["KEPLR"] = "keplr";
2074
- return WalletId2;
2075
- })(WalletId || {});
2076
535
 
2077
- export { BitcoinXConnector, BitcoinXService, EvmXConnector, EvmXService, IconHanaXConnector, IconXService, InjectiveXConnector, InjectiveXService, OKXXConnector, STACKS_PROVIDERS, SodaxWalletProvider, SolanaXConnector, SolanaXService, StacksXConnector, StacksXService, StellarWalletsKitXConnector, StellarXService, SuiXConnector, SuiXService, UnisatXConnector, WalletId, XConnector, XService, XverseXConnector, createWagmiConfig as createWagmi, createWagmiConfig, getWagmiChainId, getXChainType, getXService, isNativeToken, useBitcoinXConnectors, useEvmSwitchChain, useStacksXConnectors, useWalletProvider, useXAccount, useXAccounts, useXBalances, useXConnect, useXConnection, useXConnectors, useXDisconnect, useXService, useXSignMessage, useXWagmiStore };
536
+ export { SodaxWalletProvider };
2078
537
  //# sourceMappingURL=index.mjs.map
2079
538
  //# sourceMappingURL=index.mjs.map