@sodax/wallet-sdk-react 1.5.6-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
@@ -0,0 +1,1927 @@
1
+ 'use strict';
2
+
3
+ var types = require('@sodax/types');
4
+ var satsConnect = require('sats-connect');
5
+ var react = require('react');
6
+ var zustand = require('zustand');
7
+ var middleware = require('zustand/middleware');
8
+ var immer = require('zustand/middleware/immer');
9
+ var walletSdkCore = require('@sodax/wallet-sdk-core');
10
+ var walletBase = require('@injectivelabs/wallet-base');
11
+ var sdkTs = require('@injectivelabs/sdk-ts');
12
+ var viem = require('viem');
13
+ var actions = require('wagmi/actions');
14
+ require('wagmi');
15
+ var chains = require('wagmi/chains');
16
+ var web3_js = require('@solana/web3.js');
17
+ var splToken = require('@solana/spl-token');
18
+ var stellarWalletsKit = require('@creit.tech/stellar-wallets-kit');
19
+ var StellarSdk = require('@stellar/stellar-sdk');
20
+ var IconSdkRaw = require('icon-sdk-js');
21
+ var networks = require('@injectivelabs/networks');
22
+ var tsTypes = require('@injectivelabs/ts-types');
23
+ var walletCore = require('@injectivelabs/wallet-core');
24
+ var walletStrategy = require('@injectivelabs/wallet-strategy');
25
+ var walletCosmos = require('@injectivelabs/wallet-cosmos');
26
+ var nearConnect = require('@hot-labs/near-connect');
27
+ var nearApiJs = require('near-api-js');
28
+ var transactions = require('@stacks/transactions');
29
+ var network = require('@stacks/network');
30
+ var connect = require('@stacks/connect');
31
+ require('@tanstack/react-query');
32
+ require('viem/chains');
33
+
34
+ function _interopNamespace(e) {
35
+ if (e && e.__esModule) return e;
36
+ var n = Object.create(null);
37
+ if (e) {
38
+ Object.keys(e).forEach(function (k) {
39
+ if (k !== 'default') {
40
+ var d = Object.getOwnPropertyDescriptor(e, k);
41
+ Object.defineProperty(n, k, d.get ? d : {
42
+ enumerable: true,
43
+ get: function () { return e[k]; }
44
+ });
45
+ }
46
+ });
47
+ }
48
+ n.default = e;
49
+ return Object.freeze(n);
50
+ }
51
+
52
+ var StellarSdk__namespace = /*#__PURE__*/_interopNamespace(StellarSdk);
53
+ var IconSdkRaw__namespace = /*#__PURE__*/_interopNamespace(IconSdkRaw);
54
+
55
+ // src/core/XService.ts
56
+ var XService = class {
57
+ /** The blockchain type this service handles */
58
+ xChainType;
59
+ /** Available wallet connectors for this chain */
60
+ xConnectors = [];
61
+ constructor(xChainType) {
62
+ this.xChainType = xChainType;
63
+ }
64
+ /**
65
+ * Gets the balance of a specific token for an address
66
+ * @param address The wallet address to check
67
+ * @param xToken The token to get the balance for
68
+ * @returns Promise resolving to the token balance as a bigint
69
+ */
70
+ async getBalance(address, xToken) {
71
+ return 0n;
72
+ }
73
+ /**
74
+ * Gets balances for multiple tokens for an address
75
+ * @param address The wallet address to check
76
+ * @param xTokens Array of tokens to get balances for
77
+ * @returns Promise resolving to object mapping token addresses to balances
78
+ */
79
+ async getBalances(address, xTokens) {
80
+ if (!address) return {};
81
+ const balancePromises = xTokens.map(async (xToken) => {
82
+ const balance = await this.getBalance(address, xToken);
83
+ return { address: xToken.address, balance };
84
+ });
85
+ const balances = await Promise.all(balancePromises);
86
+ return balances.reduce((acc, { address: address2, balance }) => {
87
+ acc[address2] = balance;
88
+ return acc;
89
+ }, {});
90
+ }
91
+ /**
92
+ * Gets all available connectors for this chain
93
+ */
94
+ getXConnectors() {
95
+ return this.xConnectors;
96
+ }
97
+ /**
98
+ * Sets the available connectors for this chain
99
+ */
100
+ setXConnectors(xConnectors) {
101
+ this.xConnectors = xConnectors;
102
+ }
103
+ /**
104
+ * Gets a specific connector by its ID
105
+ * @param xConnectorId The connector ID to look up
106
+ * @returns The matching connector or undefined if not found
107
+ */
108
+ getXConnectorById(xConnectorId) {
109
+ return this.getXConnectors().find((xConnector) => xConnector.id === xConnectorId);
110
+ }
111
+ };
112
+ function getEntryDefaults(entry) {
113
+ if (!entry || typeof entry === "string") return void 0;
114
+ return entry.defaults;
115
+ }
116
+ function getRpcUrl(entry) {
117
+ if (!entry || typeof entry === "string") return void 0;
118
+ return entry.rpcUrl;
119
+ }
120
+
121
+ // src/utils/index.ts
122
+ var isNativeToken = (xToken) => {
123
+ const nativeAddresses = [
124
+ "cx0000000000000000000000000000000000000000",
125
+ "0x0000000000000000000000000000000000000000",
126
+ "inj",
127
+ "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI",
128
+ "hx0000000000000000000000000000000000000000",
129
+ "11111111111111111111111111111111",
130
+ // solana
131
+ "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA",
132
+ // stellar
133
+ "ST000000000000000000002AMW42H.nativetoken",
134
+ // stacks
135
+ "0:0"
136
+ // bitcoin
137
+ ];
138
+ return nativeAddresses.includes(xToken.address);
139
+ };
140
+ var getWagmiChainId = (xChainId) => {
141
+ const chainId = types.baseChainInfo[xChainId].chainId;
142
+ if (typeof chainId !== "number") {
143
+ throw new Error(`[wallet-sdk-react] getWagmiChainId: expected numeric chainId, got ${typeof chainId}`);
144
+ }
145
+ return chainId;
146
+ };
147
+
148
+ // src/constants.ts
149
+ var BITCOIN_DEFAULT_RPC_URL = "https://mempool.space/api";
150
+ var STELLAR_DEFAULT_HORIZON_RPC_URL = "https://horizon.stellar.org";
151
+ var STELLAR_DEFAULT_SOROBAN_RPC_URL = "https://rpc.ankr.com/stellar_soroban";
152
+ var NEAR_DEFAULT_RPC_URL = "https://1rpc.io/near";
153
+ var WALLET_METADATA = {
154
+ unisat: {
155
+ installUrl: "https://chromewebstore.google.com/detail/unisat-wallet/ppbibelpcjmhbdihakflkdcoccbgbkpo",
156
+ icon: "https://avatars.githubusercontent.com/u/125119198?s=200&v=4"
157
+ },
158
+ xverse: {
159
+ installUrl: "https://chromewebstore.google.com/detail/xverse-bitcoin-crypto-wal/idnnbdplmphpflfnlkomgpfbpcgelopg",
160
+ icon: "https://cdn.brandfetch.io/iddzGN5Rcv/w/400/h/400/theme/dark/icon.jpeg?c=1bxid64Mup7aczewSAYMX&t=1771902357797"
161
+ },
162
+ okx: {
163
+ installUrl: "https://chromewebstore.google.com/detail/okx-wallet/mcohilncbfahbmgdjkbpemcciiolgcge",
164
+ icon: "https://static.okx.com/cdn/assets/imgs/247/58E63FEA47A2B7D7.png"
165
+ },
166
+ hana: {
167
+ installUrl: "https://chromewebstore.google.com/detail/hana-wallet/jfdlamikmbghhapbgfoogdffldioobgl",
168
+ icon: "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/hana.svg"
169
+ }
170
+ };
171
+
172
+ // src/xchains/bitcoin/BitcoinXService.ts
173
+ var BitcoinXService = class _BitcoinXService extends XService {
174
+ static instance;
175
+ rpcUrl;
176
+ constructor(rpcUrl = BITCOIN_DEFAULT_RPC_URL) {
177
+ super("BITCOIN");
178
+ this.rpcUrl = rpcUrl;
179
+ }
180
+ static getInstance(rpcUrl) {
181
+ if (!_BitcoinXService.instance) {
182
+ _BitcoinXService.instance = new _BitcoinXService(rpcUrl);
183
+ } else if (rpcUrl && rpcUrl !== _BitcoinXService.instance.rpcUrl) {
184
+ _BitcoinXService.instance.rpcUrl = rpcUrl;
185
+ }
186
+ return _BitcoinXService.instance;
187
+ }
188
+ async getBalance(address, xToken) {
189
+ if (!address) return 0n;
190
+ try {
191
+ if (isNativeToken(xToken)) {
192
+ const response = await fetch(`${this.rpcUrl}/address/${address}/utxo`);
193
+ if (!response.ok) return 0n;
194
+ const utxos = await response.json();
195
+ const totalBalance = utxos.reduce((sum, utxo) => sum + utxo.value, 0);
196
+ return BigInt(totalBalance);
197
+ }
198
+ } catch {
199
+ return 0n;
200
+ }
201
+ return 0n;
202
+ }
203
+ };
204
+
205
+ // src/core/XConnector.ts
206
+ var XConnector = class {
207
+ /** The blockchain type this connector supports */
208
+ xChainType;
209
+ /** Display name of the wallet provider */
210
+ name;
211
+ /** Unique identifier for the connector */
212
+ _id;
213
+ /** Optional icon URL for the wallet provider */
214
+ _icon;
215
+ constructor(xChainType, name, id) {
216
+ this.xChainType = xChainType;
217
+ this.name = name;
218
+ this._id = id;
219
+ }
220
+ /** Get the unique identifier for this connector */
221
+ get id() {
222
+ return this._id;
223
+ }
224
+ /** Get the optional icon URL for this wallet provider */
225
+ get icon() {
226
+ return this._icon;
227
+ }
228
+ /**
229
+ * True when the wallet extension backing this connector is installed.
230
+ * Default: true (for provider-managed chains where connector presence already
231
+ * implies install — EVM via EIP-6963, Solana/Sui via adapter discovery).
232
+ * Subclasses backed by extension injection (Bitcoin, ICON, Stacks) override
233
+ * this with a window probe.
234
+ */
235
+ get isInstalled() {
236
+ return true;
237
+ }
238
+ /** URL to install the wallet extension when missing. Subclasses override. */
239
+ get installUrl() {
240
+ return void 0;
241
+ }
242
+ };
243
+
244
+ // src/xchains/bitcoin/BitcoinXConnector.ts
245
+ var BitcoinXConnector = class extends XConnector {
246
+ defaults;
247
+ constructor(name, id, defaults) {
248
+ super("BITCOIN", name, id);
249
+ this.defaults = defaults;
250
+ }
251
+ getXService() {
252
+ return BitcoinXService.getInstance();
253
+ }
254
+ };
255
+ var UnisatWalletProvider = class {
256
+ chainType = "BITCOIN";
257
+ cachedAddress;
258
+ defaults;
259
+ constructor(address, defaults) {
260
+ this.cachedAddress = address;
261
+ this.defaults = defaults;
262
+ }
263
+ // Lazy resolve so the provider can be constructed before the extension finishes injecting `window.unisat` (post-refresh rehydrate path).
264
+ get unisat() {
265
+ const u = window.unisat;
266
+ if (!u) throw new Error("Unisat wallet not available");
267
+ return u;
268
+ }
269
+ async getWalletAddress() {
270
+ try {
271
+ const accounts = await this.unisat.getAccounts();
272
+ if (accounts[0]) this.cachedAddress = accounts[0];
273
+ } catch {
274
+ }
275
+ return this.cachedAddress;
276
+ }
277
+ async getPublicKey() {
278
+ return this.unisat.getPublicKey();
279
+ }
280
+ async getAddressType(_address) {
281
+ const address = await this.getWalletAddress();
282
+ return types.detectBitcoinAddressType(address);
283
+ }
284
+ async signTransaction(psbtBase64, finalize) {
285
+ const effectiveFinalize = finalize ?? this.defaults?.defaultFinalize ?? false;
286
+ const psbtHex = Buffer.from(psbtBase64, "base64").toString("hex");
287
+ const signedHex = await this.unisat.signPsbt(psbtHex, { autoFinalized: effectiveFinalize });
288
+ return signedHex;
289
+ }
290
+ async signEcdsaMessage(message) {
291
+ return this.unisat.signMessage(message, "ecdsa");
292
+ }
293
+ async signBip322Message(message) {
294
+ return this.unisat.signMessage(message, "bip322-simple");
295
+ }
296
+ async sendBitcoin(toAddress, satoshis) {
297
+ if (satoshis > BigInt(Number.MAX_SAFE_INTEGER)) {
298
+ throw new Error(`Amount ${satoshis} satoshis exceeds safe integer range`);
299
+ }
300
+ return this.unisat.sendBitcoin(toAddress, Number(satoshis));
301
+ }
302
+ };
303
+ var UnisatXConnector = class _UnisatXConnector extends BitcoinXConnector {
304
+ walletProvider;
305
+ constructor(defaults) {
306
+ super("Unisat", "unisat", defaults);
307
+ }
308
+ static isAvailable() {
309
+ return typeof window !== "undefined" && !!window.unisat;
310
+ }
311
+ get isInstalled() {
312
+ return _UnisatXConnector.isAvailable();
313
+ }
314
+ get installUrl() {
315
+ return WALLET_METADATA.unisat.installUrl;
316
+ }
317
+ get icon() {
318
+ return WALLET_METADATA.unisat.icon;
319
+ }
320
+ async connect() {
321
+ if (!window.unisat) {
322
+ throw new Error("Unisat wallet is not installed");
323
+ }
324
+ const accounts = await window.unisat.requestAccounts();
325
+ const address = accounts[0];
326
+ if (!address) {
327
+ console.warn("[UnisatXConnector] connect: requestAccounts returned no address");
328
+ return void 0;
329
+ }
330
+ this.walletProvider = new UnisatWalletProvider(address, this.defaults);
331
+ return {
332
+ address,
333
+ xChainType: "BITCOIN"
334
+ };
335
+ }
336
+ async disconnect() {
337
+ this.walletProvider = void 0;
338
+ }
339
+ getWalletProvider() {
340
+ return this.walletProvider;
341
+ }
342
+ recreateWalletProvider(xAccount) {
343
+ if (!xAccount.address) return void 0;
344
+ return new UnisatWalletProvider(xAccount.address, this.defaults);
345
+ }
346
+ };
347
+ var XverseWalletProvider = class {
348
+ chainType = "BITCOIN";
349
+ address;
350
+ publicKey;
351
+ defaults;
352
+ constructor(address, publicKey, defaults) {
353
+ this.address = address;
354
+ this.publicKey = publicKey;
355
+ this.defaults = defaults;
356
+ }
357
+ async getWalletAddress() {
358
+ return this.address;
359
+ }
360
+ async getPublicKey() {
361
+ return this.publicKey;
362
+ }
363
+ async getAddressType(_address) {
364
+ return types.detectBitcoinAddressType(this.address);
365
+ }
366
+ /**
367
+ * Parse a base64-encoded PSBT to count the number of inputs.
368
+ * Reads the unsigned transaction from the PSBT global section.
369
+ */
370
+ countPsbtInputs(psbtBase64) {
371
+ const data = Buffer.from(psbtBase64, "base64");
372
+ let offset = 5;
373
+ const keyLen = data[offset++] ?? 0;
374
+ if (keyLen !== 1 || data[offset++] !== 0) {
375
+ return 1;
376
+ }
377
+ const firstByte = data[offset++] ?? 0;
378
+ if (firstByte === 253) offset += 2;
379
+ else if (firstByte === 254) offset += 4;
380
+ else if (firstByte === 255) offset += 8;
381
+ offset += 4;
382
+ const inputByte = data[offset] ?? 0;
383
+ if (inputByte < 253) return inputByte;
384
+ return 1;
385
+ }
386
+ async signTransaction(psbtBase64, finalize) {
387
+ const effectiveFinalize = finalize ?? this.defaults?.defaultFinalize ?? false;
388
+ const { request: request3 } = await import('sats-connect');
389
+ const inputCount = this.countPsbtInputs(psbtBase64);
390
+ const signingIndexes = Array.from({ length: inputCount }, (_, i) => i);
391
+ const response = await request3("signPsbt", {
392
+ psbt: psbtBase64,
393
+ broadcast: false,
394
+ signInputs: {
395
+ [this.address]: signingIndexes
396
+ }
397
+ });
398
+ if (response.status === "error") {
399
+ throw new Error(response.error?.message || "Xverse PSBT signing failed");
400
+ }
401
+ const result = response.result;
402
+ if (effectiveFinalize) {
403
+ return Buffer.from(result.psbt, "base64").toString("hex");
404
+ }
405
+ return result.psbt;
406
+ }
407
+ async signEcdsaMessage(message) {
408
+ const { request: request3 } = await import('sats-connect');
409
+ const response = await request3("signMessage", {
410
+ address: this.address,
411
+ message,
412
+ protocol: satsConnect.MessageSigningProtocols.ECDSA
413
+ });
414
+ if (response.status === "error") {
415
+ throw new Error(response.error?.message || "Xverse ECDSA signing failed");
416
+ }
417
+ return response.result.signature;
418
+ }
419
+ async signBip322Message(message) {
420
+ const { request: request3 } = await import('sats-connect');
421
+ const response = await request3("signMessage", {
422
+ address: this.address,
423
+ message,
424
+ protocol: satsConnect.MessageSigningProtocols.BIP322
425
+ });
426
+ if (response.status === "error") {
427
+ throw new Error(response.error?.message || "Xverse BIP322 signing failed");
428
+ }
429
+ return response.result.signature;
430
+ }
431
+ async sendBitcoin(toAddress, satoshis) {
432
+ const { request: request3 } = await import('sats-connect');
433
+ const response = await request3("sendTransfer", {
434
+ recipients: [
435
+ {
436
+ address: toAddress,
437
+ amount: Number(satoshis)
438
+ }
439
+ ]
440
+ });
441
+ if (response.status === "error") {
442
+ throw new Error(response.error?.message || "Xverse sendTransfer failed");
443
+ }
444
+ return response.result.txid;
445
+ }
446
+ };
447
+ var XVERSE_ADDRESS_TYPE_KEY = "xverse-address-type";
448
+ var XverseXConnector = class _XverseXConnector extends BitcoinXConnector {
449
+ walletProvider;
450
+ /** Address purpose used when connecting. Taproot (Ordinals) by default to match Radfi. */
451
+ addressPurpose;
452
+ constructor(defaults) {
453
+ super("Xverse", "xverse", defaults);
454
+ const saved = typeof window !== "undefined" ? localStorage.getItem(XVERSE_ADDRESS_TYPE_KEY) : null;
455
+ this.addressPurpose = saved === "segwit" ? satsConnect.AddressPurpose.Payment : satsConnect.AddressPurpose.Ordinals;
456
+ }
457
+ /** Set address purpose and persist to localStorage. */
458
+ setAddressPurpose(type) {
459
+ this.addressPurpose = type === "taproot" ? satsConnect.AddressPurpose.Ordinals : satsConnect.AddressPurpose.Payment;
460
+ if (typeof window !== "undefined") {
461
+ localStorage.setItem(XVERSE_ADDRESS_TYPE_KEY, type);
462
+ }
463
+ }
464
+ static isAvailable() {
465
+ return typeof window !== "undefined" && !!window.BitcoinProvider;
466
+ }
467
+ get isInstalled() {
468
+ return _XverseXConnector.isAvailable();
469
+ }
470
+ get installUrl() {
471
+ return WALLET_METADATA.xverse.installUrl;
472
+ }
473
+ get icon() {
474
+ return WALLET_METADATA.xverse.icon;
475
+ }
476
+ async connect() {
477
+ if (!_XverseXConnector.isAvailable()) {
478
+ throw new Error("Xverse wallet is not installed");
479
+ }
480
+ const { request: request3 } = await import('sats-connect');
481
+ const response = await request3("getAccounts", {
482
+ purposes: [this.addressPurpose],
483
+ message: "Connect to Sodax"
484
+ });
485
+ if (response.status === "error") {
486
+ throw new Error(response.error?.message || "Xverse connection failed");
487
+ }
488
+ const accounts = response.result;
489
+ const paymentAccount = accounts.find((a) => a.purpose === this.addressPurpose) || accounts[0];
490
+ if (!paymentAccount) return void 0;
491
+ this.walletProvider = new XverseWalletProvider(
492
+ paymentAccount.address,
493
+ paymentAccount.publicKey,
494
+ this.defaults
495
+ );
496
+ return {
497
+ address: paymentAccount.address,
498
+ publicKey: paymentAccount.publicKey,
499
+ xChainType: "BITCOIN"
500
+ };
501
+ }
502
+ async disconnect() {
503
+ this.walletProvider = void 0;
504
+ }
505
+ getWalletProvider() {
506
+ return this.walletProvider;
507
+ }
508
+ recreateWalletProvider(xAccount) {
509
+ if (!xAccount.address || !xAccount.publicKey) return void 0;
510
+ return new XverseWalletProvider(xAccount.address, xAccount.publicKey, this.defaults);
511
+ }
512
+ };
513
+ var OKXWalletProvider = class {
514
+ chainType = "BITCOIN";
515
+ cachedAddress;
516
+ defaults;
517
+ constructor(address, defaults) {
518
+ this.cachedAddress = address;
519
+ this.defaults = defaults;
520
+ }
521
+ // Lazy resolve so the provider can be constructed before the extension finishes injecting `window.okxwallet` (post-refresh rehydrate path).
522
+ get okx() {
523
+ const o = window.okxwallet?.bitcoin;
524
+ if (!o) throw new Error("OKX wallet not available");
525
+ return o;
526
+ }
527
+ async getWalletAddress() {
528
+ try {
529
+ const accounts = await this.okx.getAccounts();
530
+ if (accounts[0]) this.cachedAddress = accounts[0];
531
+ } catch {
532
+ }
533
+ return this.cachedAddress;
534
+ }
535
+ async getPublicKey() {
536
+ return this.okx.getPublicKey();
537
+ }
538
+ async getAddressType(_address) {
539
+ const address = await this.getWalletAddress();
540
+ return types.detectBitcoinAddressType(address);
541
+ }
542
+ async signTransaction(psbtBase64, finalize) {
543
+ const effectiveFinalize = finalize ?? this.defaults?.defaultFinalize ?? false;
544
+ const psbtHex = Buffer.from(psbtBase64, "base64").toString("hex");
545
+ return this.okx.signPsbt(psbtHex, { autoFinalized: effectiveFinalize });
546
+ }
547
+ async signEcdsaMessage(message) {
548
+ return this.okx.signMessage(message, "ecdsa");
549
+ }
550
+ async signBip322Message(message) {
551
+ return this.okx.signMessage(message, "bip322-simple");
552
+ }
553
+ async sendBitcoin(toAddress, satoshis) {
554
+ if (satoshis > BigInt(Number.MAX_SAFE_INTEGER)) {
555
+ throw new Error(`Amount ${satoshis} satoshis exceeds safe integer range`);
556
+ }
557
+ return this.okx.sendBitcoin(toAddress, Number(satoshis));
558
+ }
559
+ };
560
+ var OKXXConnector = class _OKXXConnector extends BitcoinXConnector {
561
+ walletProvider;
562
+ constructor(defaults) {
563
+ super("OKX Wallet", "okx-bitcoin", defaults);
564
+ }
565
+ static isAvailable() {
566
+ return typeof window !== "undefined" && !!window.okxwallet?.bitcoin;
567
+ }
568
+ get isInstalled() {
569
+ return _OKXXConnector.isAvailable();
570
+ }
571
+ get installUrl() {
572
+ return WALLET_METADATA.okx.installUrl;
573
+ }
574
+ get icon() {
575
+ return WALLET_METADATA.okx.icon;
576
+ }
577
+ async connect() {
578
+ const okx = window.okxwallet?.bitcoin;
579
+ if (!okx) {
580
+ throw new Error("OKX wallet is not installed");
581
+ }
582
+ const { address } = await okx.connect();
583
+ if (!address) {
584
+ console.warn("[OKXXConnector] connect: okx.connect() returned no address");
585
+ return void 0;
586
+ }
587
+ this.walletProvider = new OKXWalletProvider(address, this.defaults);
588
+ return {
589
+ address,
590
+ xChainType: "BITCOIN"
591
+ };
592
+ }
593
+ async disconnect() {
594
+ this.walletProvider = void 0;
595
+ }
596
+ getWalletProvider() {
597
+ return this.walletProvider;
598
+ }
599
+ recreateWalletProvider(xAccount) {
600
+ if (!xAccount.address) return void 0;
601
+ return new OKXWalletProvider(xAccount.address, this.defaults);
602
+ }
603
+ };
604
+
605
+ // src/shared/guards.ts
606
+ function isRecord(value) {
607
+ return typeof value === "object" && value !== null;
608
+ }
609
+ function hasStringProperty(value, key) {
610
+ return isRecord(value) && typeof value[key] === "string";
611
+ }
612
+ function hasBooleanProperty(value, key) {
613
+ return isRecord(value) && typeof value[key] === "boolean";
614
+ }
615
+ function hasFunctionProperty(value, key) {
616
+ return isRecord(value) && typeof value[key] === "function";
617
+ }
618
+ function assert(condition, message) {
619
+ if (!condition) {
620
+ throw new Error(message);
621
+ }
622
+ }
623
+ function assertSuiProviderShape(caller, client, wallet, account) {
624
+ const clientOk = isRecord(client) && hasFunctionProperty(client, "executeTransactionBlock") && hasFunctionProperty(client, "devInspectTransactionBlock") && hasFunctionProperty(client, "getCoins");
625
+ assert(clientOk, `[${caller}] invalid Sui client shape`);
626
+ const walletOk = isRecord(wallet) && hasStringProperty(wallet, "name");
627
+ assert(walletOk, `[${caller}] invalid Sui wallet shape`);
628
+ const accountOk = isRecord(account) && hasStringProperty(account, "address");
629
+ assert(accountOk, `[${caller}] invalid Sui account shape`);
630
+ }
631
+ var EvmXService = class _EvmXService extends XService {
632
+ static instance;
633
+ wagmiConfig;
634
+ constructor() {
635
+ super("EVM");
636
+ }
637
+ static getInstance() {
638
+ if (!_EvmXService.instance) {
639
+ _EvmXService.instance = new _EvmXService();
640
+ }
641
+ return _EvmXService.instance;
642
+ }
643
+ // get erc20 token balance in a chain (evm chain only)
644
+ async _getTokenBalance(address, chainId, tokenAddress) {
645
+ const publicClient = actions.getPublicClient(this.wagmiConfig, { chainId });
646
+ if (!publicClient) throw new Error("Public client not found");
647
+ const balance = await publicClient.readContract({
648
+ abi: viem.erc20Abi,
649
+ address: tokenAddress,
650
+ functionName: "balanceOf",
651
+ args: [address]
652
+ });
653
+ return balance || 0n;
654
+ }
655
+ //get native balance of the chain (evm chain only)
656
+ async _getChainBalance(address, chainId) {
657
+ const balance = await actions.getPublicClient(this.wagmiConfig, { chainId })?.getBalance({
658
+ address
659
+ });
660
+ return balance || 0n;
661
+ }
662
+ async getBalance(address, xToken) {
663
+ if (!address) return 0n;
664
+ if (!this.wagmiConfig) return 0n;
665
+ const chainId = getWagmiChainId(xToken.chainKey);
666
+ if (isNativeToken(xToken)) {
667
+ return this._getChainBalance(address, chainId);
668
+ }
669
+ throw new Error(`Unsupported token: ${xToken.symbol}`);
670
+ }
671
+ async getBalances(address, xTokens) {
672
+ if (!address) return {};
673
+ if (!this.wagmiConfig) return {};
674
+ const nativeTokenBalancePromises = xTokens.filter((xToken) => isNativeToken(xToken)).map(async (xToken) => {
675
+ const balance = await this.getBalance(address, xToken);
676
+ return { symbol: xToken.symbol, address: xToken.address, balance };
677
+ });
678
+ const nativeTokenBalances = await Promise.all(nativeTokenBalancePromises);
679
+ const tokenMap = nativeTokenBalances.reduce(
680
+ (map, { address: address2, balance }) => {
681
+ if (balance) map[address2] = balance;
682
+ return map;
683
+ },
684
+ {}
685
+ );
686
+ const nonNativeXTokens = xTokens.filter((xToken) => !isNativeToken(xToken));
687
+ const firstToken = xTokens[0];
688
+ if (!firstToken) return tokenMap;
689
+ const chainKey = firstToken.chainKey;
690
+ const viemChain = this.wagmiConfig.chains.find((chain) => chain.id === getWagmiChainId(chainKey));
691
+ const chainId = getWagmiChainId(chainKey);
692
+ const publicClient = actions.getPublicClient(this.wagmiConfig, { chainId });
693
+ if (!publicClient) throw new Error("Public client not found");
694
+ if (viemChain?.contracts?.multicall3) {
695
+ const result = await publicClient.multicall({
696
+ contracts: nonNativeXTokens.map((token) => ({
697
+ abi: viem.erc20Abi,
698
+ address: token.address,
699
+ functionName: "balanceOf",
700
+ args: [address]
701
+ }))
702
+ });
703
+ return nonNativeXTokens.reduce((acc, token, index) => {
704
+ const resultValue = result?.[index]?.result;
705
+ acc[token.address] = resultValue !== void 0 && resultValue !== null ? BigInt(resultValue) : 0n;
706
+ return acc;
707
+ }, tokenMap);
708
+ }
709
+ const nonNativeTokenBalances = await Promise.all(
710
+ nonNativeXTokens.map((token) => this._getTokenBalance(address, chainId, token.address))
711
+ );
712
+ return nonNativeXTokens.reduce((acc, token, idx) => {
713
+ acc[token.address] = nonNativeTokenBalances[idx] ?? 0n;
714
+ return acc;
715
+ }, tokenMap);
716
+ }
717
+ };
718
+ var SolanaXService = class _SolanaXService extends XService {
719
+ static instance;
720
+ connection;
721
+ wallet;
722
+ constructor() {
723
+ super("SOLANA");
724
+ }
725
+ static getInstance() {
726
+ if (!_SolanaXService.instance) {
727
+ _SolanaXService.instance = new _SolanaXService();
728
+ }
729
+ return _SolanaXService.instance;
730
+ }
731
+ async getBalance(address, xToken) {
732
+ if (!address) return BigInt(0);
733
+ const connection = this.connection;
734
+ if (!connection) {
735
+ return BigInt(0);
736
+ }
737
+ try {
738
+ if (isNativeToken(xToken)) {
739
+ const newBalance = await connection.getBalance(new web3_js.PublicKey(address));
740
+ return BigInt(newBalance);
741
+ }
742
+ const tokenAccountPubkey = splToken.getAssociatedTokenAddressSync(new web3_js.PublicKey(xToken.address), new web3_js.PublicKey(address));
743
+ const tokenAccount = await splToken.getAccount(connection, tokenAccountPubkey);
744
+ return BigInt(tokenAccount.amount);
745
+ } catch {
746
+ return BigInt(0);
747
+ }
748
+ }
749
+ };
750
+ var SuiXService = class _SuiXService extends XService {
751
+ static instance;
752
+ // Hydrated by SuiHydrator. Start undefined because wallet may not be connected yet.
753
+ // suiClient is typed structurally for the methods we call directly.
754
+ // suiWallet/suiAccount are opaque — stored and passed through to SuiWalletProvider.
755
+ suiClient;
756
+ suiWallet;
757
+ suiAccount;
758
+ constructor() {
759
+ super("SUI");
760
+ }
761
+ static getInstance() {
762
+ if (!_SuiXService.instance) {
763
+ _SuiXService.instance = new _SuiXService();
764
+ }
765
+ return _SuiXService.instance;
766
+ }
767
+ createWalletProvider() {
768
+ if (!this.suiClient || !this.suiWallet || !this.suiAccount) {
769
+ console.warn(
770
+ "[SuiXService] createWalletProvider: missing dependencies \u2014 wallet not connected yet",
771
+ { hasClient: !!this.suiClient, hasWallet: !!this.suiWallet, hasAccount: !!this.suiAccount }
772
+ );
773
+ return void 0;
774
+ }
775
+ assertSuiProviderShape("SuiXService", this.suiClient, this.suiWallet, this.suiAccount);
776
+ return new walletSdkCore.SuiWalletProvider({
777
+ client: this.suiClient,
778
+ wallet: this.suiWallet,
779
+ account: this.suiAccount
780
+ });
781
+ }
782
+ // getBalance is not used because getBalances uses getAllBalances which returns all balances
783
+ async getBalances(address, xTokens) {
784
+ if (!address || !this.suiClient) return {};
785
+ const client = this.suiClient;
786
+ try {
787
+ const balancePromises = xTokens.map(async (xToken) => {
788
+ let coinType = isNativeToken(xToken) ? "0x2::sui::SUI" : xToken.address;
789
+ if (coinType === "0x03917a812fe4a6d6bc779c5ab53f8a80ba741f8af04121193fc44e0f662e2ceb::balanced_dollar::BALANCED_DOLLAR") {
790
+ coinType = "0x3917a812fe4a6d6bc779c5ab53f8a80ba741f8af04121193fc44e0f662e2ceb::balanced_dollar::BALANCED_DOLLAR";
791
+ }
792
+ const balance = await client.getBalance({
793
+ owner: address,
794
+ coinType
795
+ });
796
+ return {
797
+ address: xToken.address,
798
+ balance: balance ? BigInt(balance.totalBalance) : void 0
799
+ };
800
+ });
801
+ const results = await Promise.all(balancePromises);
802
+ const tokenMap = {};
803
+ results.forEach((result) => {
804
+ if (result.balance !== void 0) {
805
+ tokenMap[result.address] = result.balance;
806
+ }
807
+ });
808
+ return tokenMap;
809
+ } catch (error) {
810
+ console.error("[wallet-sdk-react] SUI getBalances failed:", error);
811
+ return {};
812
+ }
813
+ }
814
+ };
815
+ var CustomSorobanServer = class extends StellarSdk.rpc.Server {
816
+ customHeaders;
817
+ constructor(serverUrl, customHeaders) {
818
+ super(serverUrl, {
819
+ allowHttp: true
820
+ });
821
+ this.customHeaders = customHeaders;
822
+ }
823
+ async simulateTransaction(tx) {
824
+ const requestOptions = {
825
+ method: "POST",
826
+ headers: {
827
+ "Content-Type": "application/json",
828
+ ...this.customHeaders
829
+ },
830
+ body: JSON.stringify({
831
+ id: 1,
832
+ jsonrpc: "2.0",
833
+ method: "simulateTransaction",
834
+ params: {
835
+ transaction: tx.toXDR()
836
+ }
837
+ })
838
+ };
839
+ const response = await fetch(`${this.serverURL}`, requestOptions);
840
+ if (!response.ok) {
841
+ throw new Error(`HTTP error simulating TX! status: ${response.status}`);
842
+ }
843
+ return response.json().then((json) => StellarSdk.rpc.parseRawSimulation(json.result));
844
+ }
845
+ async sendTransaction(tx) {
846
+ const requestOptions = {
847
+ method: "POST",
848
+ headers: {
849
+ "Content-Type": "application/json",
850
+ ...this.customHeaders
851
+ },
852
+ body: JSON.stringify({
853
+ id: 1,
854
+ jsonrpc: "2.0",
855
+ method: "sendTransaction",
856
+ params: {
857
+ transaction: tx.toXDR()
858
+ }
859
+ })
860
+ };
861
+ const response = await fetch(`${this.serverURL}`, requestOptions);
862
+ if (!response.ok) {
863
+ throw new Error(`HTTP error submitting TX! status: ${response.status}`);
864
+ }
865
+ return response.json().then((json) => json.result);
866
+ }
867
+ async getTransaction(hash) {
868
+ const requestOptions = {
869
+ method: "POST",
870
+ headers: {
871
+ "Content-Type": "application/json",
872
+ ...this.customHeaders
873
+ },
874
+ body: JSON.stringify({
875
+ id: 1,
876
+ jsonrpc: "2.0",
877
+ method: "getTransaction",
878
+ params: { hash }
879
+ })
880
+ };
881
+ const response = await fetch(`${this.serverURL}`, requestOptions);
882
+ if (!response.ok) {
883
+ throw new Error(`HTTP error getting TX! status: ${response.status}`);
884
+ }
885
+ return response.json().then((json) => json.result);
886
+ }
887
+ };
888
+ var CustomSorobanServer_default = CustomSorobanServer;
889
+ var accountToScVal = (account) => new StellarSdk.Address(account).toScVal();
890
+ var simulateTx = (tx, server) => server.simulateTransaction(tx);
891
+ var getTokenBalance = async (address, tokenId, txBuilder, server) => {
892
+ const params = [accountToScVal(address)];
893
+ const contract = new StellarSdk.Contract(tokenId);
894
+ const tx = txBuilder.addOperation(contract.call("balance", ...params)).setTimeout(StellarSdk.TimeoutInfinite).build();
895
+ const result = await simulateTx(tx, server);
896
+ if (!StellarSdk.rpc.Api.isSimulationSuccess(result)) {
897
+ throw new Error(`Simulation failed: ${JSON.stringify(result)}`);
898
+ }
899
+ return result.result ? StellarSdk.scValToBigInt(result.result.retval) : 0n;
900
+ };
901
+
902
+ // src/xchains/stellar/StellarXService.ts
903
+ var STELLAR_BASE_RESERVE_STROOPS = 5e6;
904
+ function parseXlmBalanceToStroops(balanceStr) {
905
+ const parts = balanceStr.split(".");
906
+ const whole = parts[0] ?? "0";
907
+ const frac = (parts[1] ?? "").padEnd(7, "0").slice(0, 7);
908
+ return BigInt(whole + frac);
909
+ }
910
+ var StellarXService = class _StellarXService extends XService {
911
+ static instance;
912
+ walletsKit;
913
+ server;
914
+ sorobanServer;
915
+ constructor(horizonRpcUrl, sorobanRpcUrl) {
916
+ super("STELLAR");
917
+ this.walletsKit = new stellarWalletsKit.StellarWalletsKit({
918
+ network: stellarWalletsKit.WalletNetwork.PUBLIC,
919
+ modules: stellarWalletsKit.allowAllModules()
920
+ });
921
+ this.server = new StellarSdk__namespace.Horizon.Server(horizonRpcUrl ?? STELLAR_DEFAULT_HORIZON_RPC_URL, { allowHttp: true });
922
+ this.sorobanServer = new CustomSorobanServer_default(sorobanRpcUrl ?? STELLAR_DEFAULT_SOROBAN_RPC_URL, {});
923
+ }
924
+ static getInstance(horizonRpcUrl, sorobanRpcUrl) {
925
+ if (!_StellarXService.instance) {
926
+ _StellarXService.instance = new _StellarXService(horizonRpcUrl, sorobanRpcUrl);
927
+ } else {
928
+ if (horizonRpcUrl) {
929
+ _StellarXService.instance.server = new StellarSdk__namespace.Horizon.Server(horizonRpcUrl, { allowHttp: true });
930
+ }
931
+ if (sorobanRpcUrl) {
932
+ _StellarXService.instance.sorobanServer = new CustomSorobanServer_default(sorobanRpcUrl, {});
933
+ }
934
+ }
935
+ return _StellarXService.instance;
936
+ }
937
+ async getBalance(address, xToken) {
938
+ if (!address) return BigInt(0);
939
+ const stellarAccount = await this.server.loadAccount(address);
940
+ if (xToken.symbol === "XLM") {
941
+ const xlmBalance = stellarAccount.balances.find((balance) => balance.asset_type === "native");
942
+ if (xlmBalance) {
943
+ const rawBalanceStroops = parseXlmBalanceToStroops(xlmBalance.balance);
944
+ const sellingLiabilitiesStroops = xlmBalance.selling_liabilities ? parseXlmBalanceToStroops(xlmBalance.selling_liabilities) : BigInt(0);
945
+ const reserveFields = stellarAccount;
946
+ const subentryCount = reserveFields.subentry_count ?? 0;
947
+ const numSponsoring = reserveFields.num_sponsoring ?? 0;
948
+ const numSponsored = reserveFields.num_sponsored ?? 0;
949
+ const reserveCount = Math.max(0, 2 + subentryCount + numSponsoring - numSponsored);
950
+ const minBalanceStroops = BigInt(reserveCount) * BigInt(STELLAR_BASE_RESERVE_STROOPS) + sellingLiabilitiesStroops;
951
+ const availableStroops = rawBalanceStroops > minBalanceStroops ? rawBalanceStroops - minBalanceStroops : BigInt(0);
952
+ return availableStroops;
953
+ }
954
+ } else {
955
+ try {
956
+ const txBuilder = new StellarSdk__namespace.TransactionBuilder(stellarAccount, {
957
+ fee: StellarSdk__namespace.BASE_FEE,
958
+ networkPassphrase: StellarSdk__namespace.Networks.PUBLIC
959
+ });
960
+ const balance = await getTokenBalance(address, xToken.address, txBuilder, this.sorobanServer);
961
+ return balance;
962
+ } catch (e) {
963
+ console.error(`Error while fetching token on Stellar: ${xToken.symbol}, Error: ${e}`);
964
+ }
965
+ }
966
+ return BigInt(0);
967
+ }
968
+ };
969
+
970
+ // src/xchains/stellar/StellarWalletsKitXConnector.ts
971
+ var StellarWalletsKitXConnector = class extends XConnector {
972
+ _wallet;
973
+ constructor(wallet) {
974
+ super("STELLAR", wallet.name, wallet.id);
975
+ this._wallet = wallet;
976
+ }
977
+ getXService() {
978
+ return StellarXService.getInstance();
979
+ }
980
+ async connect() {
981
+ const kit = this.getXService().walletsKit;
982
+ if (!this._wallet) {
983
+ return;
984
+ }
985
+ if (!this._wallet.isAvailable) {
986
+ throw new Error(`${this._wallet.name} is not installed. Install the wallet and reload the page.`);
987
+ }
988
+ kit.setWallet(this._wallet.id);
989
+ const { address } = await kit.getAddress();
990
+ return {
991
+ address,
992
+ xChainType: this.xChainType
993
+ };
994
+ }
995
+ async disconnect() {
996
+ }
997
+ get icon() {
998
+ return this._wallet.icon;
999
+ }
1000
+ get isInstalled() {
1001
+ return this._wallet.isAvailable;
1002
+ }
1003
+ get installUrl() {
1004
+ return this._wallet.url;
1005
+ }
1006
+ };
1007
+ var IconSdk = "default" in IconSdkRaw__namespace.default ? IconSdkRaw__namespace.default : IconSdkRaw__namespace;
1008
+ var { IconService: IconServiceConstructor, Builder: IconBuilder, Converter: IconConverter } = IconSdk;
1009
+ var CHAIN_INFO = {
1010
+ [1 /* MAINNET */]: {
1011
+ APIEndpoint: "https://ctz.solidwallet.io/api/v3"}
1012
+ };
1013
+ var IconXService = class _IconXService extends XService {
1014
+ static instance;
1015
+ iconService;
1016
+ constructor(rpcUrl) {
1017
+ super("ICON");
1018
+ const mainnetInfo = CHAIN_INFO[1 /* MAINNET */];
1019
+ if (!mainnetInfo) throw new Error("ICON mainnet chain info not found");
1020
+ this.iconService = new IconServiceConstructor(
1021
+ new IconServiceConstructor.HttpProvider(rpcUrl ?? mainnetInfo.APIEndpoint)
1022
+ );
1023
+ }
1024
+ static getInstance(rpcUrl) {
1025
+ if (!_IconXService.instance) {
1026
+ _IconXService.instance = new _IconXService(rpcUrl);
1027
+ }
1028
+ return _IconXService.instance;
1029
+ }
1030
+ async getAggregateData(requireSuccess, calls) {
1031
+ const rawTx = new IconBuilder.CallBuilder().to("cxa4aa9185e23558cff990f494c1fd2845f6cbf741").method("tryAggregate").params({ requireSuccess: IconConverter.toHex(requireSuccess ? 1 : 0), calls }).build();
1032
+ try {
1033
+ const result = await this.iconService.call(rawTx).execute();
1034
+ const aggs = result["returnData"];
1035
+ const data = aggs.map((agg) => {
1036
+ if (agg["success"] === "0x0") {
1037
+ return null;
1038
+ }
1039
+ return agg["returnData"];
1040
+ });
1041
+ return data;
1042
+ } catch (err) {
1043
+ console.error(err);
1044
+ return Array(calls.length).fill(null);
1045
+ }
1046
+ }
1047
+ async getBalances(address, xTokens) {
1048
+ if (!address) return {};
1049
+ const balances = {};
1050
+ const nativeXToken = xTokens.find((xToken) => isNativeToken(xToken));
1051
+ const nonNativeXTokens = xTokens.filter((xToken) => !isNativeToken(xToken));
1052
+ if (nativeXToken) {
1053
+ const balance = await this.iconService.getBalance(address).execute();
1054
+ balances[nativeXToken.address] = BigInt(balance.toFixed());
1055
+ }
1056
+ const cds = nonNativeXTokens.map((token) => {
1057
+ return {
1058
+ target: token.address,
1059
+ method: "balanceOf",
1060
+ params: [address]
1061
+ };
1062
+ });
1063
+ const data = await this.getAggregateData(
1064
+ false,
1065
+ cds.filter((cd) => cd.target.startsWith("cx"))
1066
+ );
1067
+ return nonNativeXTokens.reduce((agg, token, idx) => {
1068
+ const balance = data[idx];
1069
+ if (balance) {
1070
+ balances[token.address] = BigInt(balance);
1071
+ }
1072
+ return agg;
1073
+ }, balances);
1074
+ }
1075
+ };
1076
+
1077
+ // src/xchains/icon/iconex/index.tsx
1078
+ var ICONEX_RELAY_RESPONSE = "ICONEX_RELAY_RESPONSE";
1079
+ var ICONEX_RELAY_REQUEST = "ICONEX_RELAY_REQUEST";
1080
+ var request = (event) => {
1081
+ return new Promise((resolve, reject) => {
1082
+ const handler = (evt) => {
1083
+ window.removeEventListener(ICONEX_RELAY_RESPONSE, handler);
1084
+ resolve(evt.detail);
1085
+ };
1086
+ window.addEventListener(ICONEX_RELAY_RESPONSE, handler);
1087
+ window.dispatchEvent(
1088
+ new CustomEvent(ICONEX_RELAY_REQUEST, {
1089
+ detail: event
1090
+ })
1091
+ );
1092
+ });
1093
+ };
1094
+
1095
+ // src/xchains/icon/IconHanaXConnector.ts
1096
+ var isHanaWallet = (value) => {
1097
+ return isRecord(value) && (value.available === void 0 || hasBooleanProperty(value, "available"));
1098
+ };
1099
+ var IconHanaXConnector = class extends XConnector {
1100
+ constructor() {
1101
+ super("ICON", "Hana Wallet", "hana");
1102
+ }
1103
+ get isInstalled() {
1104
+ if (typeof window === "undefined") return false;
1105
+ const hanaWallet = window.hanaWallet;
1106
+ return isHanaWallet(hanaWallet) && hanaWallet.available === true;
1107
+ }
1108
+ get installUrl() {
1109
+ return WALLET_METADATA.hana.installUrl;
1110
+ }
1111
+ async connect() {
1112
+ const hanaWallet = window.hanaWallet;
1113
+ assert(isHanaWallet(hanaWallet) || hanaWallet === void 0, "[IconHanaXConnector] invalid window.hanaWallet type");
1114
+ if (!hanaWallet || !hanaWallet.available) {
1115
+ window.open(WALLET_METADATA.hana.installUrl, "_blank", "noopener,noreferrer");
1116
+ return;
1117
+ }
1118
+ const detail = await request({
1119
+ type: "REQUEST_ADDRESS" /* REQUEST_ADDRESS */
1120
+ });
1121
+ if (detail?.type === "RESPONSE_ADDRESS" /* RESPONSE_ADDRESS */) {
1122
+ return {
1123
+ address: detail?.payload,
1124
+ xChainType: this.xChainType
1125
+ };
1126
+ }
1127
+ console.warn("[IconHanaXConnector] connect: unexpected response from Hana wallet", detail);
1128
+ return void 0;
1129
+ }
1130
+ async disconnect() {
1131
+ console.log("HanaIconXConnector disconnected");
1132
+ }
1133
+ get icon() {
1134
+ return WALLET_METADATA.hana.icon;
1135
+ }
1136
+ };
1137
+ var InjectiveXService = class _InjectiveXService extends XService {
1138
+ static instance;
1139
+ walletStrategy;
1140
+ indexerGrpcAccountPortfolioApi;
1141
+ chainGrpcWasmApi;
1142
+ msgBroadcaster;
1143
+ constructor(rpcConfig) {
1144
+ super("INJECTIVE");
1145
+ const defaults = networks.getNetworkEndpoints(networks.Network.Mainnet);
1146
+ const endpoints = {
1147
+ ...defaults,
1148
+ indexer: rpcConfig?.indexer || defaults.indexer,
1149
+ grpc: rpcConfig?.grpc || defaults.grpc
1150
+ };
1151
+ this.walletStrategy = new walletStrategy.WalletStrategy({
1152
+ chainId: tsTypes.ChainId.Mainnet,
1153
+ strategies: {},
1154
+ evmOptions: {
1155
+ evmChainId: chains.mainnet.id,
1156
+ rpcUrl: chains.mainnet.rpcUrls.default.http[0]
1157
+ }
1158
+ });
1159
+ this.indexerGrpcAccountPortfolioApi = new sdkTs.IndexerGrpcAccountPortfolioApi(endpoints.indexer);
1160
+ this.chainGrpcWasmApi = new sdkTs.ChainGrpcWasmApi(endpoints.grpc);
1161
+ this.msgBroadcaster = new walletCore.MsgBroadcaster({
1162
+ walletStrategy: this.walletStrategy,
1163
+ network: networks.Network.Mainnet,
1164
+ endpoints
1165
+ });
1166
+ }
1167
+ /**
1168
+ * @param rpcConfig - Only applied on first call. Subsequent calls return the
1169
+ * existing instance unchanged — gRPC/Indexer clients are built in the
1170
+ * constructor and can't be rebuilt at runtime. Pass the desired endpoints
1171
+ * via `SodaxWalletProvider.config.rpcConfig` once at app init.
1172
+ */
1173
+ static getInstance(rpcConfig) {
1174
+ if (!_InjectiveXService.instance) {
1175
+ _InjectiveXService.instance = new _InjectiveXService(rpcConfig);
1176
+ }
1177
+ return _InjectiveXService.instance;
1178
+ }
1179
+ async getBalance(address, xToken) {
1180
+ if (!address) return 0n;
1181
+ const portfolio = await this.indexerGrpcAccountPortfolioApi.fetchAccountPortfolioBalances(address);
1182
+ const xTokenAddress = xToken.address;
1183
+ const balance = portfolio.bankBalancesList.find((_balance) => _balance.denom === xTokenAddress);
1184
+ if (balance) {
1185
+ return BigInt(balance.amount);
1186
+ }
1187
+ return 0n;
1188
+ }
1189
+ };
1190
+ var WALLET_ICONS = {
1191
+ metamask: "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/metamask.svg",
1192
+ keplr: "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/keplr.svg",
1193
+ leap: "https://assets.leapwallet.io/logos/leap-cosmos-logo.svg",
1194
+ rabby: "https://raw.githubusercontent.com/RabbyHub/logo/master/symbol.svg",
1195
+ phantom: "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/phantom.svg",
1196
+ "okx-wallet": "https://static.okx.com/cdn/assets/imgs/247/58E63FEA47A2B7D7.png",
1197
+ "trust-wallet": "https://trustwallet.com/assets/images/media/assets/twLogo.svg"
1198
+ };
1199
+ var InjectiveXConnector = class extends XConnector {
1200
+ wallet;
1201
+ constructor(name, wallet) {
1202
+ super("INJECTIVE", name, wallet);
1203
+ this.wallet = wallet;
1204
+ }
1205
+ getXService() {
1206
+ return InjectiveXService.getInstance();
1207
+ }
1208
+ async connect() {
1209
+ if (walletBase.isCosmosBrowserWallet(this.wallet) && !walletCosmos.isCosmosWalletInstalled(this.wallet)) {
1210
+ console.warn(`[InjectiveXConnector] connect: ${this.wallet} cosmos wallet not installed`);
1211
+ return void 0;
1212
+ }
1213
+ const walletStrategy = this.getXService().walletStrategy;
1214
+ await walletStrategy.setWallet(this.wallet);
1215
+ const addresses = await walletStrategy.getAddresses();
1216
+ if (!addresses?.length) {
1217
+ console.warn(`[InjectiveXConnector] connect: ${this.wallet} returned no addresses`);
1218
+ return void 0;
1219
+ }
1220
+ const firstAddress = addresses[0];
1221
+ if (!firstAddress) {
1222
+ console.warn(`[InjectiveXConnector] connect: ${this.wallet} returned empty addresses array`);
1223
+ return void 0;
1224
+ }
1225
+ const address = walletBase.isEvmBrowserWallet(this.wallet) ? sdkTs.getInjectiveAddress(firstAddress) : firstAddress;
1226
+ return {
1227
+ address,
1228
+ xChainType: this.xChainType
1229
+ };
1230
+ }
1231
+ async disconnect() {
1232
+ if (walletBase.isEvmBrowserWallet(this.wallet)) {
1233
+ const walletStrategy = this.getXService().walletStrategy;
1234
+ await walletStrategy.setWallet(this.wallet);
1235
+ await walletStrategy.disconnect();
1236
+ }
1237
+ }
1238
+ get icon() {
1239
+ return WALLET_ICONS[this.wallet];
1240
+ }
1241
+ get isInstalled() {
1242
+ if (walletBase.isCosmosBrowserWallet(this.wallet)) {
1243
+ return walletCosmos.isCosmosWalletInstalled(this.wallet);
1244
+ }
1245
+ return true;
1246
+ }
1247
+ };
1248
+
1249
+ // src/xchains/bitcoin/bitcoinSignGuards.ts
1250
+ function hasSignBip322(c) {
1251
+ return "signBip322Message" in c && typeof c.signBip322Message === "function";
1252
+ }
1253
+ function hasSignEcdsa(c) {
1254
+ return "signEcdsaMessage" in c && typeof c.signEcdsaMessage === "function";
1255
+ }
1256
+ var NearXService = class _NearXService extends XService {
1257
+ static instance;
1258
+ walletSelector;
1259
+ rpcUrl;
1260
+ /**
1261
+ * @param rpcUrl - Used by `getBalance` via `JsonRpcProvider({ url: rpcUrl })`.
1262
+ * Does NOT affect `walletSelector` — `@hot-labs/near-connect` only accepts
1263
+ * the network preset name (`'mainnet'`/`'testnet'`) and fetches RPC internally.
1264
+ * Custom RPC is therefore read-only for balance queries.
1265
+ */
1266
+ constructor(rpcUrl = NEAR_DEFAULT_RPC_URL) {
1267
+ super("NEAR");
1268
+ this.rpcUrl = rpcUrl;
1269
+ this.walletSelector = new nearConnect.NearConnector({
1270
+ network: "mainnet",
1271
+ logger: console,
1272
+ autoConnect: true,
1273
+ excludedWallets: ["okx-wallet"]
1274
+ });
1275
+ }
1276
+ /**
1277
+ * @param rpcUrl - Re-applied on every call (matches StacksXService semantics).
1278
+ * `rpcUrl` only drives `getBalance` via a per-call `JsonRpcProvider`, so it's
1279
+ * safe to update at runtime — no persistent chain client to rebuild.
1280
+ */
1281
+ static getInstance(rpcUrl) {
1282
+ if (!_NearXService.instance) {
1283
+ _NearXService.instance = new _NearXService(rpcUrl);
1284
+ } else if (rpcUrl) {
1285
+ _NearXService.instance.rpcUrl = rpcUrl;
1286
+ }
1287
+ return _NearXService.instance;
1288
+ }
1289
+ async getBalance(address, xToken) {
1290
+ const provider = new nearApiJs.JsonRpcProvider({ url: this.rpcUrl });
1291
+ if (xToken.symbol === "NEAR") {
1292
+ const account = await provider.viewAccount({ accountId: address ?? "" });
1293
+ return BigInt(account.amount);
1294
+ }
1295
+ const res = await provider.callFunction({
1296
+ contractId: xToken.address,
1297
+ method: "ft_balance_of",
1298
+ args: { account_id: address }
1299
+ });
1300
+ return BigInt(res ?? 0);
1301
+ }
1302
+ };
1303
+
1304
+ // src/xchains/near/NearXConnector.ts
1305
+ var NearXConnector = class extends XConnector {
1306
+ _wallet;
1307
+ constructor(wallet) {
1308
+ super("NEAR", wallet.manifest.name, wallet.manifest.id);
1309
+ this._wallet = wallet;
1310
+ }
1311
+ getXService() {
1312
+ return NearXService.getInstance();
1313
+ }
1314
+ async connect() {
1315
+ const walletSelector = this.getXService().walletSelector;
1316
+ const wallet = await walletSelector.connect({ walletId: this._wallet.manifest.id });
1317
+ const accounts = await wallet.getAccounts();
1318
+ if (accounts.length === 0 || accounts[0] === void 0) {
1319
+ console.warn(`[NearXConnector] connect: ${this._wallet.manifest.name} returned no accounts`);
1320
+ return void 0;
1321
+ }
1322
+ return {
1323
+ address: accounts[0].accountId,
1324
+ xChainType: this.xChainType
1325
+ };
1326
+ }
1327
+ async disconnect() {
1328
+ const walletSelector = this.getXService().walletSelector;
1329
+ await walletSelector.disconnect(this._wallet);
1330
+ }
1331
+ get icon() {
1332
+ return this._wallet.manifest.icon;
1333
+ }
1334
+ };
1335
+ var StacksXService = class _StacksXService extends XService {
1336
+ static instance;
1337
+ network;
1338
+ constructor(network$1) {
1339
+ super("STACKS");
1340
+ this.network = network.networkFrom(network$1 || "mainnet");
1341
+ }
1342
+ static getInstance(network$1) {
1343
+ if (!_StacksXService.instance) {
1344
+ _StacksXService.instance = new _StacksXService(network$1);
1345
+ } else if (network$1) {
1346
+ _StacksXService.instance.network = network.networkFrom(network$1);
1347
+ }
1348
+ return _StacksXService.instance;
1349
+ }
1350
+ async getBalance(address, xToken) {
1351
+ if (!address) return 0n;
1352
+ if (xToken.symbol === "STX") {
1353
+ const url = `${this.network.client.baseUrl}/extended/v1/address/${address}/balances`;
1354
+ try {
1355
+ const response = await fetch(url);
1356
+ if (!response.ok) {
1357
+ throw new Error(`Error fetching data: ${response.statusText}`);
1358
+ }
1359
+ const data = await response.json();
1360
+ return BigInt(data.stx.balance);
1361
+ } catch (error) {
1362
+ console.error("Error fetching STX balance:", error);
1363
+ return 0n;
1364
+ }
1365
+ }
1366
+ const parts = xToken.address.split(".");
1367
+ const contractAddress = parts[0] ?? "";
1368
+ const contractName = parts[1] ?? "";
1369
+ try {
1370
+ const result = await transactions.fetchCallReadOnlyFunction({
1371
+ contractAddress,
1372
+ contractName,
1373
+ functionName: "get-balance",
1374
+ functionArgs: [transactions.Cl.principal(address)],
1375
+ network: this.network,
1376
+ senderAddress: address
1377
+ });
1378
+ return result.value.value;
1379
+ } catch (error) {
1380
+ console.error("Error fetching token balance:", error);
1381
+ return 0n;
1382
+ }
1383
+ }
1384
+ };
1385
+ function getProviderFromId(id) {
1386
+ return id.split(".").reduce((acc, part) => acc?.[part], window);
1387
+ }
1388
+ var StacksXConnector = class extends XConnector {
1389
+ config;
1390
+ constructor(config) {
1391
+ super("STACKS", config.name, config.id);
1392
+ this.config = config;
1393
+ }
1394
+ async connect() {
1395
+ const provider = this.getProvider();
1396
+ if (!provider) {
1397
+ throw new Error(`${this.config.name} is not installed. Install the extension and reload the page.`);
1398
+ }
1399
+ const response = await connect.request({ provider }, "stx_getAddresses");
1400
+ const stxAddress = response.addresses.find((a) => a.purpose === "stacks");
1401
+ if (!stxAddress) {
1402
+ console.warn(
1403
+ `[StacksXConnector] ${this.config.name}: no address with purpose="stacks" returned from stx_getAddresses`,
1404
+ response.addresses
1405
+ );
1406
+ return void 0;
1407
+ }
1408
+ return {
1409
+ address: stxAddress.address,
1410
+ xChainType: this.xChainType
1411
+ };
1412
+ }
1413
+ async disconnect() {
1414
+ connect.disconnect();
1415
+ }
1416
+ get icon() {
1417
+ return this.config.icon;
1418
+ }
1419
+ get isInstalled() {
1420
+ if (typeof window === "undefined") return false;
1421
+ return getProviderFromId(this.config.id) !== void 0;
1422
+ }
1423
+ get installUrl() {
1424
+ return this.config.installUrl;
1425
+ }
1426
+ getProvider() {
1427
+ return getProviderFromId(this.config.id);
1428
+ }
1429
+ };
1430
+
1431
+ // src/xchains/stacks/constants.ts
1432
+ var LEATHER_ICON = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCIgdmlld0JveD0iMCAwIDEyOCAxMjgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxMjgiIGhlaWdodD0iMTI4IiByeD0iMjYuODM4NyIgZmlsbD0iIzEyMTAwRiIvPgo8cGF0aCBkPSJNNzQuOTE3MSA1Mi43MTE0QzgyLjQ3NjYgNTEuNTQwOCA5My40MDg3IDQzLjU4MDQgOTMuNDA4NyAzNy4zNzYxQzkzLjQwODcgMzUuNTAzMSA5MS44OTY4IDM0LjIxNTQgODkuNjg3MSAzNC4yMTU0Qzg1LjUwMDQgMzQuMjE1NCA3OC40MDYxIDQwLjUzNjggNzQuOTE3MSA1Mi43MTE0Wk0zOS45MTEgODMuNDk5MUMzMC4wMjU2IDgzLjQ5OTEgMjkuMjExNSA5My4zMzI0IDM5LjA5NjkgOTMuMzMyNEM0My41MTYzIDkzLjMzMjQgNDguODY2MSA5MS41NzY0IDUxLjY1NzMgODguNDE1N0M0Ny41ODY4IDg0LjkwMzggNDQuMjE0MSA4My40OTkxIDM5LjkxMSA4My40OTkxWk0xMDIuODI5IDc5LjI4NDhDMTAzLjQxIDk1Ljc5MDcgOTUuMDM2OSAxMDUuMDM5IDgwLjg0ODQgMTA1LjAzOUM3Mi40NzQ4IDEwNS4wMzkgNjguMjg4MSAxMDEuODc4IDU5LjMzMyA5Ni4wMjQ5QzU0LjY4MSAxMDEuMTc2IDQ1Ljg0MjMgMTA1LjAzOSAzOC41MTU0IDEwNS4wMzlDMTMuMjc4NSAxMDUuMDM5IDE0LjMyNTIgNzIuODQ2MyA0MC4wMjczIDcyLjg0NjNDNDUuMzc3MSA3Mi44NDYzIDQ5LjkxMjggNzQuMjUxMSA1NS43Mjc3IDc3Ljg4TDU5LjU2NTYgNjQuNDE3N0M0My43NDg5IDYwLjA4NjQgMzUuODQwNSA0Ny45MTE4IDQzLjYzMjYgMzAuNDY5M0g1Ni4xOTI5QzQ5LjIxNSA0Mi4wNTg2IDUzLjk4MzIgNTEuNjU3OCA2Mi44MjIgNTIuNzExNEM2Ny41OTAzIDM1LjczNzIgNzcuODI0NiAyMi41MDkgOTEuNDMxNiAyMi41MDlDOTkuMTA3NCAyMi41MDkgMTA1LjE1NSAyNy41NDI4IDEwNS4xNTUgMzYuNjczN0MxMDUuMTU1IDUxLjMwNjYgODYuMDgxOSA2My4yNDcxIDcxLjY2MDcgNjQuNDE3N0w2NS43Mjk1IDg1LjM3MjFDNzIuNDc0OCA5My4yMTUzIDkxLjE5OSAxMDAuODI0IDkxLjE5OSA3OS4yODQ4SDEwMi44MjlaIiBmaWxsPSIjRjVGMUVEIi8+Cjwvc3ZnPgo=";
1433
+ var XVERSE_ICON = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MDAiIGhlaWdodD0iNjAwIj48ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGZpbGw9IiMxNzE3MTciIGQ9Ik0wIDBoNjAwdjYwMEgweiIvPjxwYXRoIGZpbGw9IiNGRkYiIGZpbGwtcnVsZT0ibm9uemVybyIgZD0iTTQ0MCA0MzUuNHYtNTFjMC0yLS44LTMuOS0yLjItNS4zTDIyMCAxNjIuMmE3LjYgNy42IDAgMCAwLTUuNC0yLjJoLTUxLjFjLTIuNSAwLTQuNiAyLTQuNiA0LjZ2NDcuM2MwIDIgLjggNCAyLjIgNS40bDc4LjIgNzcuOGE0LjYgNC42IDAgMCAxIDAgNi41bC03OSA3OC43Yy0xIC45LTEuNCAyLTEuNCAzLjJ2NTJjMCAyLjQgMiA0LjUgNC42IDQuNUgyNDljMi42IDAgNC42LTIgNC42LTQuNlY0MDVjMC0xLjIuNS0yLjQgMS40LTMuM2w0Mi40LTQyLjJhNC42IDQuNiAwIDAgMSA2LjQgMGw3OC43IDc4LjRhNy42IDcuNiAwIDAgMCA1LjQgMi4yaDQ3LjVjMi41IDAgNC42LTIgNC42LTQuNloiLz48cGF0aCBmaWxsPSIjRUU3QTMwIiBmaWxsLXJ1bGU9Im5vbnplcm8iIGQ9Ik0zMjUuNiAyMjcuMmg0Mi44YzIuNiAwIDQuNiAyLjEgNC42IDQuNnY0Mi42YzAgNCA1IDYuMSA4IDMuMmw1OC43LTU4LjVjLjgtLjggMS4zLTIgMS4zLTMuMnYtNTEuMmMwLTIuNi0yLTQuNi00LjYtNC42TDM4NCAxNjBjLTEuMiAwLTIuNC41LTMuMyAxLjNsLTU4LjQgNTguMWE0LjYgNC42IDAgMCAwIDMuMiA3LjhaIi8+PC9nPjwvc3ZnPg==";
1434
+ var ASIGNA_ICON = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMDEwMCIgZD0iTTAgMGgzMnYzMkgweiIvPjxwYXRoIGZpbGw9InVybCgjYSkiIGQ9Ik0xNS4xMSA1LjU1YTMgMyAwIDAgMC0xLjgyIDEuM2wtLjA1LjA4LS40My43Mi0uMDcuMTEtLjUuODUtLjA1LjA5LTEuMjkgMi4xOC0uMDQuMDctLjQ3LjgtLjA2LjEtLjQ2Ljc4LS4wNy4xMS0xLjYzIDIuNzYtLjA3LjExLS4zOC42Ni0uMDUuMDgtLjczIDEuMjQtLjM1LjYtLjQuNjctLjA1LjA5TDUuMSAyMC43bC0uMTEuMTgtLjE0LjIzLS4wNy4xMy0uMzMuNTUtLjA0LjA3di4wMWExLjI2IDEuMjYgMCAwIDAtLjE0LjQ3IDEuMzEgMS4zMSAwIDAgMCAxLjI0IDEuNGgxLjVsLjA1LS4wNi4wNC0uMDYuODctMS4yMS4wNS0uMDguNzctMS4wNy4wNS0uMDcuNC0uNTcuMDUtLjA2LjI0LS4zNGExLjUyIDEuNTIgMCAwIDEgMS4zOS0uNjIgMS41IDEuNSAwIDAgMSAuNjQuMiAxLjQ3IDEuNDcgMCAwIDEgLjczIDEuMjcgMS40NCAxLjQ0IDAgMCAxLS4yNy44NGwtLjYzLjg4LS4wNS4wNy0uMzIuNDUtLjA2LjA4LS4wOC4xMi0uMTIuMTYtLjA1LjA4aDIuMTNhMi4zMiAyLjMyIDAgMCAwIDEuNzctLjk2bDEuMTgtMS42My43Ny0xLjA4IDEuMy0xLjhhMS4yNCAxLjI0IDAgMCAxIC41NS0uNDNsLjA4LS4wM2ExLjMgMS4zIDAgMCAxIC4zLS4wNiAxLjI4IDEuMjggMCAwIDEgMS4xNS41NGwuMTEuMmExLjEzIDEuMTMgMCAwIDEgLjEuNDEgMS4xOSAxLjE5IDAgMCAxLS4yMy43N2wtLjAzLjA1LS41Ny44LS43Ljk4LS4yNy4zN2ExLjIyIDEuMjIgMCAwIDAtLjIuNSAxLjA1IDEuMDUgMCAwIDAtLjAyLjIzdi4wNmExLjE3IDEuMTcgMCAwIDAgLjE0LjQzbC4wMi4wNS4wNy4xYTEuNDQgMS40NCAwIDAgMCAuMS4xMWwuMDUuMDYuMDEuMDFhMS44IDEuOCAwIDAgMCAuMTQuMWMwIC4wMi4wMi4wMy4wNC4wM2ExIDEgMCAwIDAgLjA4LjA1bC4wNy4wNGExLjI1IDEuMjUgMCAwIDAgLjUuMWg2LjljLjEgMCAuMi0uMDEuMjktLjAzbC4wNi0uMDJhMS4yNyAxLjI3IDAgMCAwIC4yNy0uMS41Ny41NyAwIDAgMCAuMDctLjAzIDEuMjEgMS4yMSAwIDAgMCAuMjYtLjE5bC4wOC0uMDdhLjkyLjkyIDAgMCAwIC4xNS0uMTkgMS41NSAxLjU1IDAgMCAwIC4wOS0uMTdsLjAyLS4wNWExLjIyIDEuMjIgMCAwIDAgLjA4LS4yNnYtLjA0bC4wMi0uMDh2LS4wOGExLjMyIDEuMzIgMCAwIDAtLjItLjc0bC0xLjYtMi42NC0uMDYtLjEtLjItLjMyLS4zMy0uNTR2LS4wMWwtLjA1LS4wOC0xLjMtMi4xNS0uMDctLjEtLjA0LS4wNi0uOC0xLjMyLS4wNC0uMDctLjItLjM0LS4xLS4xNC0uMS0uMTYtLjUzLS45LS4xMy0uMi0uMDktLjE0LTIuMTctMy41Ny0uMDQtLjA3LS43Mi0xLjE5LS4wNS0uMDctLjQtLjY1YTIuNjUgMi42NSAwIDAgMC0uMy0uNCAyLjk2IDIuOTYgMCAwIDAtLjk3LS43NCAzLjA0IDMuMDQgMCAwIDAtMS4zLS4zYy0uMjUgMC0uNS4wNC0uNzQuMVoiLz48cGF0aCBmaWxsPSJ1cmwoI2IpIiBkPSJNMTkgMTYuM2E1LjQ1IDUuNDUgMCAwIDAtLjgzIDEuNTZsLS4wNC4xNWExLjM2IDEuMzYgMCAwIDEgLjI4LS4xNiAxLjI0IDEuMjQgMCAwIDEgLjM4LS4wOGguMWExLjI4IDEuMjggMCAwIDEgMS4wNS41NGMuMDQuMDYuMDguMTMuMS4yYTEuMjQgMS4yNCAwIDAgMSAuMDkuMjcgMS4xOSAxLjE5IDAgMCAxLS4yLjkxbC0uMDQuMDUtLjU3Ljc5LS43Ljk5LS4yNy4zN2ExLjIzIDEuMjMgMCAwIDAtLjIuNDIgMS4wNiAxLjA2IDAgMCAwLS4wMi4zMXYuMDZhMS4xNyAxLjE3IDAgMCAwIC4xNi40Ny45My45MyAwIDAgMCAuMDcuMSAxLjUgMS41IDAgMCAwIC4xLjEybC4wNS4wNmguMDFhMS45NCAxLjk0IDAgMCAwIC4wOS4wOCAxIDEgMCAwIDAgLjE3LjFsLjA3LjA0YTEuMjUgMS4yNSAwIDAgMCAuNS4xaDYuOWMuMSAwIC4yIDAgLjI4LS4wMmwuMDctLjAyYTEuMzIgMS4zMiAwIDAgMCAuMzQtLjEzbC4xNi0uMS4wMy0uMDNhMS4yOSAxLjI5IDAgMCAwIC4yLS4yIDIuNDMgMi40MyAwIDAgMCAuMTItLjE3Yy4wMy0uMDMuMDUtLjA4LjA3LS4xMmwuMDItLjA1YTEuMjEgMS4yMSAwIDAgMCAuMDktLjN2LS4wOGwuMDEtLjA5YTEuMzIgMS4zMiAwIDAgMC0uMi0uNzNsLTEuNi0yLjY0LS4wNi0uMS0uMi0uMzItLjMzLS41NHYtLjAybC0uMDUtLjA3LTEuMy0yLjE1LS4xMi0uMDctLjA3LS4wNGE0Ljk0IDQuOTQgMCAwIDAtMi40Ni0uNjdjLTEuMDMgMC0xLjc2LjU3LTIuMjYgMS4yWiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMi4yOSAyMS4wOGMwIC4yOS0uMDkuNTgtLjI3Ljg0bC0xLjMxIDEuODRIN2wyLjUyLTMuNTNhMS41NCAxLjU0IDAgMCAxIDIuMS0uMzZjLjQzLjI4LjY2Ljc0LjY2IDEuMloiLz48cGF0aCBmaWxsPSIjMDAwIiBkPSJNMTEuMTYgMjEuMjVhLjU2LjU2IDAgMCAxLS41Ny41NS41Ni41NiAwIDAgMS0uNTctLjU2LjU2LjU2IDAgMCAxIC41Ny0uNTUuNTYuNTYgMCAwIDEgLjU3LjU2WiIvPjxkZWZzPjxsaW5lYXJHcmFkaWVudCBpZD0iYSIgeDE9IjE1LjIzIiB4Mj0iMTkuMyIgeTE9IjI1Ljc4IiB5Mj0iNi4xMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPjxzdG9wIHN0b3AtY29sb3I9IiM2NTIyRjQiLz48c3RvcCBvZmZzZXQ9Ii41NSIgc3RvcC1jb2xvcj0iIzlCNkJGRiIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0E1ODVGRiIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJiIiB4MT0iMjIuNTkiIHgyPSIyNC44IiB5MT0iMjQuNzEiIHkyPSIxNS41MyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPjxzdG9wIHN0b3AtY29sb3I9IiM0MjFGOEIiLz48c3RvcCBvZmZzZXQ9Ii41NSIgc3RvcC1jb2xvcj0iIzcyMzBGRiIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzk3NzNGRiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjwvc3ZnPg==";
1435
+ var FORDEFI_ICON = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDIiIGhlaWdodD0iNDIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZmlsbD0iIzEwMTExNCIgZD0iTTAgMGg0MnY0MkgweiIvPgogIDxwYXRoIGQ9Ik0xOS40NyAyNi44OUg1djMuNTdhNC41NyA0LjU3IDAgMCAwIDQuNTggNC41N2g1LjgzbDQuMDYtOC4xNFoiIGZpbGw9IiM3OTk0RkYiLz4KICA8cGF0aCBkPSJNNSAxNy40aDI3LjU4bC0zLjIgNi43OEg1VjE3LjRaIiBmaWxsPSIjNDg2REZGIi8+CiAgPHBhdGggZD0iTTE0LjY3IDdINXY3LjY4aDMzVjdoLTkuNjd2NS43NGgtMlY3aC05LjY3djUuNzRoLTEuOTlWN1oiIGZpbGw9IiM1Q0QxRkEiLz4KPC9zdmc+Cg==";
1436
+ var STACKS_PROVIDERS = [
1437
+ {
1438
+ id: "LeatherProvider",
1439
+ name: "Leather",
1440
+ icon: LEATHER_ICON,
1441
+ installUrl: "https://chrome.google.com/webstore/detail/hiro-wallet/ldinpeekobnhjjdofggfgjlcehhmanlj"
1442
+ },
1443
+ {
1444
+ id: "XverseProviders.BitcoinProvider",
1445
+ name: "Xverse Wallet",
1446
+ icon: XVERSE_ICON,
1447
+ installUrl: "https://chrome.google.com/webstore/detail/xverse-wallet/idnnbdplmphpflfnlkomgpfbpcgelopg"
1448
+ },
1449
+ {
1450
+ id: "AsignaProvider",
1451
+ name: "Asigna Multisig",
1452
+ icon: ASIGNA_ICON,
1453
+ installUrl: "https://stx.asigna.io/"
1454
+ },
1455
+ {
1456
+ id: "FordefiProviders.UtxoProvider",
1457
+ name: "Fordefi",
1458
+ icon: FORDEFI_ICON,
1459
+ installUrl: "https://chromewebstore.google.com/detail/fordefi/hcmehenccjdmfbojapcbcofkgdpbnlle"
1460
+ }
1461
+ ];
1462
+
1463
+ // src/chainRegistry.ts
1464
+ function defineChain2(factory) {
1465
+ return factory;
1466
+ }
1467
+ function narrowConnectors(items, chainType) {
1468
+ return items.filter((item) => {
1469
+ if (!(item instanceof XConnector)) {
1470
+ console.warn(
1471
+ `[chainRegistry] ${chainType} connector "${item.id}" must extend XConnector \u2014 skipping. Implement the abstract XConnector class instead of raw IXConnector for full SDK support.`
1472
+ );
1473
+ return false;
1474
+ }
1475
+ return true;
1476
+ });
1477
+ }
1478
+ function readConnectorsOverride(chainType, walletConfig) {
1479
+ return walletConfig?.[chainType]?.connectors;
1480
+ }
1481
+ function hasChainOfType(chainType, walletConfig) {
1482
+ return walletConfig[chainType] !== void 0;
1483
+ }
1484
+ var createDefaultActions = (chainType, service, getStore) => ({
1485
+ connect: async (xConnectorId) => {
1486
+ const connector = service.getXConnectorById(xConnectorId);
1487
+ return connector?.connect();
1488
+ },
1489
+ disconnect: async () => {
1490
+ const store = getStore();
1491
+ const connectorId = store.xConnections[chainType]?.xConnectorId;
1492
+ const connector = connectorId ? service.getXConnectorById(connectorId) : void 0;
1493
+ try {
1494
+ await connector?.disconnect();
1495
+ } finally {
1496
+ store.unsetXConnection(chainType);
1497
+ }
1498
+ },
1499
+ getConnectors: () => getStore().xConnectorsByChain[chainType] ?? [],
1500
+ getConnection: () => getStore().xConnections[chainType]
1501
+ });
1502
+ var chainRegistry = {
1503
+ EVM: defineChain2({
1504
+ createService: () => EvmXService.getInstance(),
1505
+ displayName: "EVM",
1506
+ defaultConnectors: () => [],
1507
+ providerManaged: true
1508
+ }),
1509
+ SUI: defineChain2({
1510
+ createService: () => SuiXService.getInstance(),
1511
+ displayName: "Sui",
1512
+ defaultConnectors: () => [],
1513
+ providerManaged: true
1514
+ }),
1515
+ SOLANA: defineChain2({
1516
+ createService: () => SolanaXService.getInstance(),
1517
+ displayName: "Solana",
1518
+ defaultConnectors: () => [],
1519
+ providerManaged: true
1520
+ }),
1521
+ BITCOIN: defineChain2({
1522
+ createService: (walletConfig) => BitcoinXService.getInstance(getRpcUrl(walletConfig?.BITCOIN?.chains?.[types.ChainKeys.BITCOIN_MAINNET])),
1523
+ displayName: "Bitcoin",
1524
+ defaultConnectors: (walletConfig) => {
1525
+ const defaults = getEntryDefaults(
1526
+ walletConfig?.BITCOIN?.chains?.[types.ChainKeys.BITCOIN_MAINNET]
1527
+ );
1528
+ return [new UnisatXConnector(defaults), new XverseXConnector(defaults), new OKXXConnector(defaults)];
1529
+ },
1530
+ providerManaged: false,
1531
+ createActions: (service, getStore) => ({
1532
+ ...createDefaultActions("BITCOIN", service, getStore),
1533
+ signMessage: async (message) => {
1534
+ const store = getStore();
1535
+ const connection = store.xConnections.BITCOIN;
1536
+ const connector = connection?.xConnectorId ? service.getXConnectorById(connection.xConnectorId) : void 0;
1537
+ if (!(connector instanceof BitcoinXConnector)) {
1538
+ throw new Error("Bitcoin wallet not connected");
1539
+ }
1540
+ const address = connection?.xAccount.address;
1541
+ if (!address) throw new Error("Bitcoin address not found");
1542
+ const addressType = types.detectBitcoinAddressType(address);
1543
+ switch (addressType) {
1544
+ case "P2WPKH":
1545
+ case "P2TR": {
1546
+ if (!hasSignBip322(connector)) {
1547
+ throw new Error(`${connector.id} does not support BIP-322 signing`);
1548
+ }
1549
+ return connector.signBip322Message(message);
1550
+ }
1551
+ case "P2SH":
1552
+ case "P2PKH": {
1553
+ if (!hasSignEcdsa(connector)) {
1554
+ throw new Error(`${connector.id} does not support ECDSA signing`);
1555
+ }
1556
+ return connector.signEcdsaMessage(message);
1557
+ }
1558
+ default: {
1559
+ const _exhaustiveCheck = addressType;
1560
+ throw new Error(`Unhandled Bitcoin address type: ${_exhaustiveCheck}`);
1561
+ }
1562
+ }
1563
+ }
1564
+ }),
1565
+ createWalletProvider: (service, getStore) => {
1566
+ const store = getStore();
1567
+ const connection = store.xConnections.BITCOIN;
1568
+ if (!connection?.xConnectorId) return void 0;
1569
+ const connector = service.getXConnectorById(connection.xConnectorId);
1570
+ if (!(connector instanceof BitcoinXConnector)) return void 0;
1571
+ return connector.recreateWalletProvider(connection.xAccount);
1572
+ }
1573
+ }),
1574
+ INJECTIVE: defineChain2({
1575
+ createService: (walletConfig) => InjectiveXService.getInstance(walletConfig?.INJECTIVE?.chains?.[types.ChainKeys.INJECTIVE_MAINNET]),
1576
+ displayName: "Injective",
1577
+ defaultConnectors: () => [
1578
+ new InjectiveXConnector("MetaMask", walletBase.Wallet.Metamask),
1579
+ new InjectiveXConnector("Keplr", walletBase.Wallet.Keplr),
1580
+ new InjectiveXConnector("Leap", walletBase.Wallet.Leap)
1581
+ ],
1582
+ providerManaged: false,
1583
+ createActions: (service, getStore) => ({
1584
+ ...createDefaultActions("INJECTIVE", service, getStore),
1585
+ signMessage: async (message) => {
1586
+ const store = getStore();
1587
+ const address = store.xConnections.INJECTIVE?.xAccount.address;
1588
+ if (!address) throw new Error("Injective address not found");
1589
+ const ethereumAddress = sdkTs.getEthereumAddress(address);
1590
+ const walletStrategy = service.walletStrategy;
1591
+ const res = await walletStrategy.signArbitrary(
1592
+ walletStrategy.getWallet() === walletBase.Wallet.Metamask ? ethereumAddress : address,
1593
+ message
1594
+ );
1595
+ if (!res) throw new Error("Injective signature not found");
1596
+ return res;
1597
+ }
1598
+ }),
1599
+ createWalletProvider: (service, getStore) => {
1600
+ if (!service) return void 0;
1601
+ const defaults = getEntryDefaults(
1602
+ getStore().walletConfig?.INJECTIVE?.chains?.[types.ChainKeys.INJECTIVE_MAINNET]
1603
+ );
1604
+ return new walletSdkCore.InjectiveWalletProvider({ msgBroadcaster: service.msgBroadcaster, defaults });
1605
+ }
1606
+ }),
1607
+ STELLAR: defineChain2({
1608
+ createService: (walletConfig) => {
1609
+ const stellarRpc = walletConfig?.STELLAR?.chains?.[types.ChainKeys.STELLAR_MAINNET];
1610
+ return StellarXService.getInstance(stellarRpc?.horizonRpcUrl, stellarRpc?.sorobanRpcUrl);
1611
+ },
1612
+ displayName: "Stellar",
1613
+ defaultConnectors: () => [],
1614
+ providerManaged: false,
1615
+ discoverConnectors: async (service, getStore) => {
1616
+ const STELLAR_DISCOVER_DELAYS_MS = [0, 100, 500];
1617
+ let lastIds = "";
1618
+ for (const delay of STELLAR_DISCOVER_DELAYS_MS) {
1619
+ if (delay) await new Promise((r) => setTimeout(r, delay));
1620
+ const wallets = await service.walletsKit.getSupportedWallets();
1621
+ const connectors = wallets.filter((w) => w.isAvailable).map((w) => new StellarWalletsKitXConnector(w));
1622
+ const ids = connectors.map((c) => c.id).sort().join(",");
1623
+ if (ids === lastIds) break;
1624
+ lastIds = ids;
1625
+ service.setXConnectors(connectors);
1626
+ getStore().setXConnectors("STELLAR", connectors);
1627
+ }
1628
+ },
1629
+ createActions: (service, getStore) => ({
1630
+ ...createDefaultActions("STELLAR", service, getStore),
1631
+ signMessage: async (message) => {
1632
+ const res = await service.walletsKit.signMessage(message);
1633
+ return res.signedMessage;
1634
+ }
1635
+ }),
1636
+ createWalletProvider: (service, getStore) => {
1637
+ if (!service?.walletsKit) return void 0;
1638
+ const defaults = getEntryDefaults(
1639
+ getStore().walletConfig?.STELLAR?.chains?.[types.ChainKeys.STELLAR_MAINNET]
1640
+ );
1641
+ return new walletSdkCore.StellarWalletProvider({
1642
+ type: "BROWSER_EXTENSION",
1643
+ walletsKit: service.walletsKit,
1644
+ network: "PUBLIC",
1645
+ defaults
1646
+ });
1647
+ }
1648
+ }),
1649
+ // ICON: signMessage not implemented — Hana wallet does not expose a signing API.
1650
+ // connect/disconnect use createDefaultActions (no createActions override needed).
1651
+ ICON: defineChain2({
1652
+ createService: (walletConfig) => IconXService.getInstance(getRpcUrl(walletConfig?.ICON?.chains?.[types.ChainKeys.ICON_MAINNET])),
1653
+ displayName: "ICON",
1654
+ defaultConnectors: () => [new IconHanaXConnector()],
1655
+ providerManaged: false,
1656
+ createWalletProvider: (_service, getStore) => {
1657
+ const store = getStore();
1658
+ const address = store.xConnections.ICON?.xAccount.address;
1659
+ if (!address) return void 0;
1660
+ const chainInfo = CHAIN_INFO[1 /* MAINNET */];
1661
+ if (!chainInfo) throw new Error("ICON mainnet chain info not found");
1662
+ const defaults = getEntryDefaults(
1663
+ store.walletConfig?.ICON?.chains?.[types.ChainKeys.ICON_MAINNET]
1664
+ );
1665
+ return new walletSdkCore.IconWalletProvider({
1666
+ walletAddress: address,
1667
+ rpcUrl: chainInfo.APIEndpoint,
1668
+ defaults
1669
+ });
1670
+ }
1671
+ }),
1672
+ NEAR: defineChain2({
1673
+ createService: (walletConfig) => NearXService.getInstance(getRpcUrl(walletConfig?.NEAR?.chains?.[types.ChainKeys.NEAR_MAINNET])),
1674
+ displayName: "NEAR",
1675
+ defaultConnectors: () => [],
1676
+ providerManaged: false,
1677
+ discoverConnectors: async (service, getStore) => {
1678
+ await service.walletSelector.whenManifestLoaded;
1679
+ const connectors = service.walletSelector.availableWallets.map((w) => new NearXConnector(w));
1680
+ service.setXConnectors(connectors);
1681
+ getStore().setXConnectors("NEAR", connectors);
1682
+ },
1683
+ createActions: (service, getStore) => ({
1684
+ ...createDefaultActions("NEAR", service, getStore),
1685
+ disconnect: async () => {
1686
+ try {
1687
+ service.walletSelector.disconnect();
1688
+ } finally {
1689
+ getStore().unsetXConnection("NEAR");
1690
+ }
1691
+ }
1692
+ }),
1693
+ createWalletProvider: (service, getStore) => {
1694
+ if (!service?.walletSelector) return void 0;
1695
+ const defaults = getEntryDefaults(
1696
+ getStore().walletConfig?.NEAR?.chains?.[types.ChainKeys.NEAR_MAINNET]
1697
+ );
1698
+ return new walletSdkCore.NearWalletProvider({ wallet: service.walletSelector, defaults });
1699
+ }
1700
+ }),
1701
+ STACKS: defineChain2({
1702
+ createService: (walletConfig) => StacksXService.getInstance(walletConfig?.STACKS?.chains?.[types.ChainKeys.STACKS_MAINNET]),
1703
+ displayName: "Stacks",
1704
+ defaultConnectors: () => STACKS_PROVIDERS.map((c) => new StacksXConnector(c)),
1705
+ providerManaged: false,
1706
+ createWalletProvider: (service, getStore) => {
1707
+ const store = getStore();
1708
+ const connection = store.xConnections.STACKS;
1709
+ const address = connection?.xAccount.address;
1710
+ if (!address) return void 0;
1711
+ const connector = connection?.xConnectorId ? service.getXConnectorById(connection.xConnectorId) : void 0;
1712
+ const provider = connector instanceof StacksXConnector ? connector.getProvider() : void 0;
1713
+ const defaults = getEntryDefaults(
1714
+ store.walletConfig?.STACKS?.chains?.[types.ChainKeys.STACKS_MAINNET]
1715
+ );
1716
+ return new walletSdkCore.StacksWalletProvider({ address, provider, defaults });
1717
+ }
1718
+ })
1719
+ };
1720
+ var createChainServices = (walletConfig, getStore) => {
1721
+ const xServices = {};
1722
+ const xConnectorsByChain = {};
1723
+ const enabledChains = [];
1724
+ const chainActions = {};
1725
+ for (const chainType of types.ChainTypeArr) {
1726
+ if (!hasChainOfType(chainType, walletConfig)) continue;
1727
+ const factory = chainRegistry[chainType];
1728
+ if (!factory) continue;
1729
+ const service = factory.createService(walletConfig);
1730
+ xServices[chainType] = service;
1731
+ enabledChains.push(chainType);
1732
+ if (!factory.providerManaged) {
1733
+ const override = readConnectorsOverride(chainType, walletConfig);
1734
+ const connectors = override ? narrowConnectors(override, chainType) : factory.defaultConnectors(walletConfig);
1735
+ service.setXConnectors(connectors);
1736
+ xConnectorsByChain[chainType] = connectors;
1737
+ chainActions[chainType] = factory.createActions ? factory.createActions(service, getStore) : createDefaultActions(chainType, service, getStore);
1738
+ if (factory.discoverConnectors) {
1739
+ factory.discoverConnectors(service, getStore).catch((err) => {
1740
+ console.warn(`[wallet-sdk-react] discoverConnectors failed for ${chainType}:`, err);
1741
+ });
1742
+ }
1743
+ }
1744
+ }
1745
+ return { xServices, xConnectorsByChain, enabledChains, chainActions };
1746
+ };
1747
+
1748
+ // src/useXWalletStore.ts
1749
+ var useXWalletStore = zustand.create()(
1750
+ middleware.devtools(
1751
+ middleware.persist(
1752
+ immer.immer((set, get) => ({
1753
+ xServices: {},
1754
+ xConnections: {},
1755
+ xConnectorsByChain: {},
1756
+ enabledChains: [],
1757
+ chainActions: {},
1758
+ walletProviders: {},
1759
+ walletConfig: void 0,
1760
+ userDisconnected: {},
1761
+ setXConnection: (xChainType, xConnection) => {
1762
+ set((state) => {
1763
+ state.xConnections[xChainType] = xConnection;
1764
+ });
1765
+ const factory = chainRegistry[xChainType]?.createWalletProvider;
1766
+ if (factory) {
1767
+ const service = get().xServices[xChainType];
1768
+ if (service) {
1769
+ const provider = factory(service, () => get());
1770
+ get().setWalletProvider(xChainType, provider);
1771
+ }
1772
+ }
1773
+ },
1774
+ unsetXConnection: (xChainType) => {
1775
+ set((state) => {
1776
+ delete state.xConnections[xChainType];
1777
+ delete state.walletProviders[xChainType];
1778
+ });
1779
+ },
1780
+ setXConnectors: (xChainType, connectors) => {
1781
+ set((state) => {
1782
+ state.xConnectorsByChain[xChainType] = connectors;
1783
+ });
1784
+ },
1785
+ registerChainActions: (xChainType, actions) => {
1786
+ set((state) => {
1787
+ state.chainActions[xChainType] = actions;
1788
+ });
1789
+ },
1790
+ setWalletProvider: (xChainType, provider) => {
1791
+ set((state) => {
1792
+ if (provider) {
1793
+ state.walletProviders[xChainType] = provider;
1794
+ } else {
1795
+ delete state.walletProviders[xChainType];
1796
+ }
1797
+ });
1798
+ },
1799
+ getWalletProvider: (xChainType) => {
1800
+ if (!xChainType) return void 0;
1801
+ return get().walletProviders[xChainType];
1802
+ },
1803
+ initChainServices: (walletConfig) => {
1804
+ const result = createChainServices(walletConfig, () => get());
1805
+ set((state) => {
1806
+ state.xServices = result.xServices;
1807
+ state.enabledChains = result.enabledChains;
1808
+ Object.assign(state.xConnectorsByChain, result.xConnectorsByChain);
1809
+ Object.assign(state.chainActions, result.chainActions);
1810
+ });
1811
+ set({ walletConfig });
1812
+ },
1813
+ cleanupDisabledConnections: () => {
1814
+ set((state) => {
1815
+ for (const chainType of types.ChainTypeArr) {
1816
+ if (state.xConnections[chainType] && !state.enabledChains.includes(chainType)) {
1817
+ delete state.xConnections[chainType];
1818
+ delete state.walletProviders[chainType];
1819
+ }
1820
+ }
1821
+ });
1822
+ },
1823
+ markUserDisconnected: (xChainType) => {
1824
+ set((state) => {
1825
+ state.userDisconnected[xChainType] = true;
1826
+ });
1827
+ },
1828
+ clearUserDisconnected: (xChainType) => {
1829
+ set((state) => {
1830
+ delete state.userDisconnected[xChainType];
1831
+ });
1832
+ }
1833
+ })),
1834
+ {
1835
+ // key kept as 'xwagmi-store' for backward compat — existing users won't lose persisted connections on upgrade
1836
+ name: "xwagmi-store",
1837
+ storage: middleware.createJSONStorage(() => localStorage),
1838
+ partialize: (state) => ({
1839
+ xConnections: state.xConnections,
1840
+ userDisconnected: state.userDisconnected
1841
+ })
1842
+ }
1843
+ ),
1844
+ { name: "xwagmi-store" }
1845
+ )
1846
+ );
1847
+ zustand.create()(
1848
+ middleware.devtools(
1849
+ immer.immer((set) => ({
1850
+ walletModal: { kind: "closed" },
1851
+ open: () => {
1852
+ set((state) => {
1853
+ state.walletModal = { kind: "chainSelect" };
1854
+ });
1855
+ },
1856
+ close: () => {
1857
+ set((state) => {
1858
+ state.walletModal = { kind: "closed" };
1859
+ });
1860
+ },
1861
+ back: () => {
1862
+ set((state) => {
1863
+ const current = state.walletModal;
1864
+ switch (current.kind) {
1865
+ case "walletSelect":
1866
+ state.walletModal = { kind: "chainSelect" };
1867
+ return;
1868
+ case "connecting":
1869
+ case "error":
1870
+ state.walletModal = { kind: "walletSelect", chainType: current.chainType };
1871
+ return;
1872
+ case "success":
1873
+ state.walletModal = { kind: "closed" };
1874
+ return;
1875
+ }
1876
+ });
1877
+ },
1878
+ selectChain: (chainType) => {
1879
+ set((state) => {
1880
+ state.walletModal = { kind: "walletSelect", chainType };
1881
+ });
1882
+ },
1883
+ setConnecting: (chainType, connector) => {
1884
+ set((state) => {
1885
+ state.walletModal = { kind: "connecting", chainType, connector };
1886
+ });
1887
+ },
1888
+ setSuccess: (chainType, connector, account) => {
1889
+ set((state) => {
1890
+ state.walletModal = { kind: "success", chainType, connector, account };
1891
+ });
1892
+ },
1893
+ setError: (chainType, connector, error) => {
1894
+ set((state) => {
1895
+ state.walletModal = { kind: "error", chainType, connector, error };
1896
+ });
1897
+ }
1898
+ })),
1899
+ { name: "wallet-modal-store" }
1900
+ )
1901
+ );
1902
+
1903
+ // src/hooks/useXService.ts
1904
+ function useXService({ xChainType } = {}) {
1905
+ const xService = useXWalletStore((state) => xChainType ? state.xServices[xChainType] : void 0);
1906
+ return xService;
1907
+ }
1908
+ var WalletConfigContext = react.createContext(null);
1909
+ WalletConfigContext.Provider;
1910
+
1911
+ // src/xchains/bitcoin/useBitcoinXConnectors.ts
1912
+ function useBitcoinXConnectors() {
1913
+ const xService = useXService({ xChainType: "BITCOIN" });
1914
+ return react.useMemo(() => {
1915
+ const connectors = xService?.getXConnectors() ?? [];
1916
+ return connectors.filter((c) => c instanceof BitcoinXConnector);
1917
+ }, [xService]);
1918
+ }
1919
+
1920
+ exports.BitcoinXConnector = BitcoinXConnector;
1921
+ exports.BitcoinXService = BitcoinXService;
1922
+ exports.OKXXConnector = OKXXConnector;
1923
+ exports.UnisatXConnector = UnisatXConnector;
1924
+ exports.XverseXConnector = XverseXConnector;
1925
+ exports.useBitcoinXConnectors = useBitcoinXConnectors;
1926
+ //# sourceMappingURL=index.cjs.map
1927
+ //# sourceMappingURL=index.cjs.map