@sodax/wallet-sdk-react 1.3.0-beta → 1.3.1-beta-rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,11 +1,17 @@
1
- import { baseChainInfo, ChainTypeArr, 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 } from '@sodax/types';
1
+ import { detectBitcoinAddressType, baseChainInfo, ChainTypeArr, 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 } from '@sodax/types';
2
2
  import { NearConnector } from '@hot-labs/near-connect';
3
3
  import { JsonRpcProvider } from 'near-api-js';
4
+ import { AddressPurpose, MessageSigningProtocols } from 'sats-connect';
5
+ import React2, { useMemo, useCallback, useEffect } from 'react';
6
+ import { useCurrentAccount, useCurrentWallet, useConnectWallet, useWallets, useDisconnectWallet, useSignPersonalMessage, SuiClientProvider, WalletProvider, useSuiClient } from '@mysten/dapp-kit';
7
+ import { useWallet, ConnectionProvider, WalletProvider as WalletProvider$1, useConnection } from '@solana/wallet-adapter-react';
8
+ import { useConnections, useAccount, useConnect, useConnectors, useDisconnect, useSwitchChain, usePublicClient, useWalletClient, useSignMessage, WagmiProvider, createConfig, http, useConfig } from 'wagmi';
9
+ import { create } from 'zustand';
10
+ import { devtools, persist, createJSONStorage } from 'zustand/middleware';
11
+ import { immer } from 'zustand/middleware/immer';
4
12
  import { erc20Abi, defineChain } from 'viem';
5
13
  import { getPublicClient } from 'wagmi/actions';
6
- import { useConnections, useAccount, useConnect, useConnectors, useDisconnect, useSwitchChain, usePublicClient, useWalletClient, useSignMessage, WagmiProvider, createConfig, http, useConfig } from 'wagmi';
7
14
  import { mainnet, avalanche, arbitrum, base, bsc, sonic, optimism, polygon, lightlinkPhoenix, kaia, redbellyMainnet } from 'wagmi/chains';
8
- import * as IconSdkRaw from 'icon-sdk-js';
9
15
  import { getNetworkEndpoints, Network } from '@injectivelabs/networks';
10
16
  import { IndexerGrpcAccountPortfolioApi, ChainGrpcWasmApi, getInjectiveAddress, getEthereumAddress } from '@injectivelabs/sdk-ts';
11
17
  import { ChainId } from '@injectivelabs/ts-types';
@@ -18,18 +24,12 @@ import { getAssociatedTokenAddressSync, getAccount } from '@solana/spl-token';
18
24
  import { StellarWalletsKit, allowAllModules, WalletNetwork } from '@creit.tech/stellar-wallets-kit';
19
25
  import * as StellarSdk from '@stellar/stellar-sdk';
20
26
  import { SorobanRpc, Address, Contract, TimeoutInfinite, scValToBigInt, xdr } from '@stellar/stellar-sdk';
21
- import React2, { useMemo, useCallback, useEffect } from 'react';
22
- import { useCurrentAccount, useCurrentWallet, useConnectWallet, useWallets, useDisconnectWallet, useSignPersonalMessage, SuiClientProvider, WalletProvider, useSuiClient } from '@mysten/dapp-kit';
23
- import { useWallet, ConnectionProvider, WalletProvider as WalletProvider$1, useConnection } from '@solana/wallet-adapter-react';
24
- import { create } from 'zustand';
25
- import { devtools, persist, createJSONStorage } from 'zustand/middleware';
26
- import { immer } from 'zustand/middleware/immer';
27
- import { QueryClient, useMutation, useQuery, keepPreviousData, QueryClientProvider } from '@tanstack/react-query';
27
+ import * as IconSdkRaw from 'icon-sdk-js';
28
+ import { QueryClient, useMutation, useQuery, QueryClientProvider } from '@tanstack/react-query';
28
29
  import { mainnet as mainnet$1 } from 'viem/chains';
29
30
  import { NearWalletProvider, SolanaWalletProvider, StellarWalletProvider, InjectiveWalletProvider, IconWalletProvider, SuiWalletProvider, EvmWalletProvider } from '@sodax/wallet-sdk-core';
30
31
  import { getFullnodeUrl } from '@mysten/sui/client';
31
32
  import { UnsafeBurnerWalletAdapter } from '@solana/wallet-adapter-wallets';
32
- import { AnchorProvider } from '@coral-xyz/anchor';
33
33
 
34
34
  // src/actions/getXChainType.ts
35
35
  function getXChainType(xChainId) {
@@ -125,6 +125,8 @@ var NearXService = class _NearXService extends XService {
125
125
  // src/actions/getXService.ts
126
126
  function getXService(xChainType) {
127
127
  switch (xChainType) {
128
+ case "BITCOIN":
129
+ return BitcoinXService.getInstance();
128
130
  case "EVM":
129
131
  return EvmXService.getInstance();
130
132
  case "SUI":
@@ -169,14 +171,341 @@ var isNativeToken = (xToken) => {
169
171
  "hx0000000000000000000000000000000000000000",
170
172
  "11111111111111111111111111111111",
171
173
  // solana
172
- "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA"
173
- // stellar,
174
+ "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA",
175
+ // stellar
176
+ "0:0"
177
+ // bitcoin
174
178
  ];
175
179
  return nativeAddresses.includes(xToken.address);
176
180
  };
177
181
  var getWagmiChainId = (xChainId) => {
178
182
  return baseChainInfo[xChainId].chainId;
179
183
  };
184
+
185
+ // src/xchains/bitcoin/BitcoinXService.ts
186
+ var BitcoinXService = class _BitcoinXService extends XService {
187
+ constructor(rpcUrl = "https://mempool.space/api") {
188
+ super("BITCOIN");
189
+ this.rpcUrl = rpcUrl;
190
+ }
191
+ static getInstance(rpcUrl) {
192
+ if (!_BitcoinXService.instance) {
193
+ _BitcoinXService.instance = new _BitcoinXService(rpcUrl);
194
+ } else if (rpcUrl && rpcUrl !== _BitcoinXService.instance.rpcUrl) {
195
+ _BitcoinXService.instance.rpcUrl = rpcUrl;
196
+ }
197
+ return _BitcoinXService.instance;
198
+ }
199
+ async getBalance(address, xToken) {
200
+ if (!address) return 0n;
201
+ try {
202
+ if (isNativeToken(xToken)) {
203
+ const response = await fetch(`${this.rpcUrl}/address/${address}/utxo`);
204
+ if (!response.ok) return 0n;
205
+ const utxos = await response.json();
206
+ const totalBalance = utxos.reduce((sum, utxo) => sum + utxo.value, 0);
207
+ return BigInt(totalBalance);
208
+ }
209
+ } catch {
210
+ return 0n;
211
+ }
212
+ return 0n;
213
+ }
214
+ };
215
+
216
+ // src/xchains/bitcoin/BitcoinXConnector.ts
217
+ var BitcoinXConnector = class extends XConnector {
218
+ constructor(name, id) {
219
+ super("BITCOIN", name, id);
220
+ }
221
+ getXService() {
222
+ return BitcoinXService.getInstance();
223
+ }
224
+ };
225
+ var UnisatWalletProvider = class {
226
+ constructor(unisat, address) {
227
+ this.unisat = unisat;
228
+ this.cachedAddress = address;
229
+ }
230
+ async getWalletAddress() {
231
+ try {
232
+ const accounts = await this.unisat.getAccounts();
233
+ if (accounts[0]) this.cachedAddress = accounts[0];
234
+ } catch {
235
+ }
236
+ return this.cachedAddress;
237
+ }
238
+ async getPublicKey() {
239
+ return this.unisat.getPublicKey();
240
+ }
241
+ async getAddressType(_address) {
242
+ const address = await this.getWalletAddress();
243
+ return detectBitcoinAddressType(address);
244
+ }
245
+ async signTransaction(psbtBase64, finalize = false) {
246
+ const psbtHex = Buffer.from(psbtBase64, "base64").toString("hex");
247
+ const signedHex = await this.unisat.signPsbt(psbtHex, { autoFinalized: finalize });
248
+ return signedHex;
249
+ }
250
+ async signEcdsaMessage(message) {
251
+ return this.unisat.signMessage(message, "ecdsa");
252
+ }
253
+ async signBip322Message(message) {
254
+ return this.unisat.signMessage(message, "bip322-simple");
255
+ }
256
+ async sendBitcoin(toAddress, satoshis) {
257
+ if (satoshis > BigInt(Number.MAX_SAFE_INTEGER)) {
258
+ throw new Error(`Amount ${satoshis} satoshis exceeds safe integer range`);
259
+ }
260
+ return this.unisat.sendBitcoin(toAddress, Number(satoshis));
261
+ }
262
+ };
263
+ var UnisatXConnector = class extends BitcoinXConnector {
264
+ constructor() {
265
+ super("Unisat", "unisat");
266
+ }
267
+ static isAvailable() {
268
+ return typeof window !== "undefined" && !!window.unisat;
269
+ }
270
+ get icon() {
271
+ return "https://avatars.githubusercontent.com/u/125119198?s=200&v=4";
272
+ }
273
+ async connect() {
274
+ if (!window.unisat) {
275
+ throw new Error("Unisat wallet is not installed");
276
+ }
277
+ const accounts = await window.unisat.requestAccounts();
278
+ const address = accounts[0];
279
+ if (!address) return void 0;
280
+ this.walletProvider = new UnisatWalletProvider(window.unisat, address);
281
+ return {
282
+ address,
283
+ xChainType: "BITCOIN"
284
+ };
285
+ }
286
+ async disconnect() {
287
+ this.walletProvider = void 0;
288
+ }
289
+ getWalletProvider() {
290
+ return this.walletProvider;
291
+ }
292
+ recreateWalletProvider(xAccount) {
293
+ if (!window.unisat || !xAccount.address) return void 0;
294
+ return new UnisatWalletProvider(window.unisat, xAccount.address);
295
+ }
296
+ };
297
+ var XverseWalletProvider = class {
298
+ constructor(address, publicKey) {
299
+ this.address = address;
300
+ this.publicKey = publicKey;
301
+ }
302
+ async getWalletAddress() {
303
+ return this.address;
304
+ }
305
+ async getPublicKey() {
306
+ return this.publicKey;
307
+ }
308
+ async getAddressType(_address) {
309
+ return detectBitcoinAddressType(this.address);
310
+ }
311
+ /**
312
+ * Parse a base64-encoded PSBT to count the number of inputs.
313
+ * Reads the unsigned transaction from the PSBT global section.
314
+ */
315
+ countPsbtInputs(psbtBase64) {
316
+ const data = Buffer.from(psbtBase64, "base64");
317
+ let offset = 5;
318
+ const keyLen = data[offset++] ?? 0;
319
+ if (keyLen !== 1 || data[offset++] !== 0) {
320
+ return 1;
321
+ }
322
+ const firstByte = data[offset++] ?? 0;
323
+ if (firstByte === 253) offset += 2;
324
+ else if (firstByte === 254) offset += 4;
325
+ else if (firstByte === 255) offset += 8;
326
+ offset += 4;
327
+ const inputByte = data[offset] ?? 0;
328
+ if (inputByte < 253) return inputByte;
329
+ return 1;
330
+ }
331
+ async signTransaction(psbtBase64, finalize = false) {
332
+ const { request: request2 } = await import('sats-connect');
333
+ const inputCount = this.countPsbtInputs(psbtBase64);
334
+ const signingIndexes = Array.from({ length: inputCount }, (_, i) => i);
335
+ const response = await request2("signPsbt", {
336
+ psbt: psbtBase64,
337
+ broadcast: false,
338
+ signInputs: {
339
+ [this.address]: signingIndexes
340
+ }
341
+ });
342
+ if (response.status === "error") {
343
+ throw new Error(response.error?.message || "Xverse PSBT signing failed");
344
+ }
345
+ const result = response.result;
346
+ if (finalize) {
347
+ return Buffer.from(result.psbt, "base64").toString("hex");
348
+ }
349
+ return result.psbt;
350
+ }
351
+ async signEcdsaMessage(message) {
352
+ const { request: request2 } = await import('sats-connect');
353
+ const response = await request2("signMessage", {
354
+ address: this.address,
355
+ message,
356
+ protocol: MessageSigningProtocols.ECDSA
357
+ });
358
+ if (response.status === "error") {
359
+ throw new Error(response.error?.message || "Xverse ECDSA signing failed");
360
+ }
361
+ return response.result.signature;
362
+ }
363
+ async signBip322Message(message) {
364
+ const { request: request2 } = await import('sats-connect');
365
+ const response = await request2("signMessage", {
366
+ address: this.address,
367
+ message,
368
+ protocol: MessageSigningProtocols.BIP322
369
+ });
370
+ if (response.status === "error") {
371
+ throw new Error(response.error?.message || "Xverse BIP322 signing failed");
372
+ }
373
+ return response.result.signature;
374
+ }
375
+ async sendBitcoin(toAddress, satoshis) {
376
+ const { request: request2 } = await import('sats-connect');
377
+ const response = await request2("sendTransfer", {
378
+ recipients: [
379
+ {
380
+ address: toAddress,
381
+ amount: Number(satoshis)
382
+ }
383
+ ]
384
+ });
385
+ if (response.status === "error") {
386
+ throw new Error(response.error?.message || "Xverse sendTransfer failed");
387
+ }
388
+ return response.result.txid;
389
+ }
390
+ };
391
+ var XverseXConnector = class _XverseXConnector extends BitcoinXConnector {
392
+ constructor() {
393
+ super("Xverse", "xverse");
394
+ }
395
+ static isAvailable() {
396
+ return typeof window !== "undefined" && !!window.BitcoinProvider;
397
+ }
398
+ get icon() {
399
+ return "https://cdn.brandfetch.io/iddzGN5Rcv/w/400/h/400/theme/dark/icon.jpeg?c=1bxid64Mup7aczewSAYMX&t=1771902357797";
400
+ }
401
+ async connect() {
402
+ if (!_XverseXConnector.isAvailable()) {
403
+ throw new Error("Xverse wallet is not installed");
404
+ }
405
+ const { request: request2 } = await import('sats-connect');
406
+ const response = await request2("getAccounts", {
407
+ purposes: [AddressPurpose.Payment],
408
+ message: "Connect to Sodax"
409
+ });
410
+ if (response.status === "error") {
411
+ throw new Error(response.error?.message || "Xverse connection failed");
412
+ }
413
+ const accounts = response.result;
414
+ const paymentAccount = accounts.find((a) => a.purpose === AddressPurpose.Payment) || accounts[0];
415
+ if (!paymentAccount) return void 0;
416
+ this.walletProvider = new XverseWalletProvider(
417
+ paymentAccount.address,
418
+ paymentAccount.publicKey
419
+ );
420
+ return {
421
+ address: paymentAccount.address,
422
+ publicKey: paymentAccount.publicKey,
423
+ xChainType: "BITCOIN"
424
+ };
425
+ }
426
+ async disconnect() {
427
+ this.walletProvider = void 0;
428
+ }
429
+ getWalletProvider() {
430
+ return this.walletProvider;
431
+ }
432
+ recreateWalletProvider(xAccount) {
433
+ if (!xAccount.address || !xAccount.publicKey) return void 0;
434
+ return new XverseWalletProvider(xAccount.address, xAccount.publicKey);
435
+ }
436
+ };
437
+ var OKXWalletProvider = class {
438
+ constructor(okx, address) {
439
+ this.okx = okx;
440
+ this.cachedAddress = address;
441
+ }
442
+ async getWalletAddress() {
443
+ try {
444
+ const accounts = await this.okx.getAccounts();
445
+ if (accounts[0]) this.cachedAddress = accounts[0];
446
+ } catch {
447
+ }
448
+ return this.cachedAddress;
449
+ }
450
+ async getPublicKey() {
451
+ return this.okx.getPublicKey();
452
+ }
453
+ async getAddressType(_address) {
454
+ const address = await this.getWalletAddress();
455
+ return detectBitcoinAddressType(address);
456
+ }
457
+ async signTransaction(psbtBase64, finalize = false) {
458
+ const psbtHex = Buffer.from(psbtBase64, "base64").toString("hex");
459
+ return this.okx.signPsbt(psbtHex, { autoFinalized: finalize });
460
+ }
461
+ async signEcdsaMessage(message) {
462
+ return this.okx.signMessage(message, "ecdsa");
463
+ }
464
+ async signBip322Message(message) {
465
+ return this.okx.signMessage(message, "bip322-simple");
466
+ }
467
+ async sendBitcoin(toAddress, satoshis) {
468
+ if (satoshis > BigInt(Number.MAX_SAFE_INTEGER)) {
469
+ throw new Error(`Amount ${satoshis} satoshis exceeds safe integer range`);
470
+ }
471
+ return this.okx.sendBitcoin(toAddress, Number(satoshis));
472
+ }
473
+ };
474
+ var OKXXConnector = class extends BitcoinXConnector {
475
+ constructor() {
476
+ super("OKX Wallet", "okx-bitcoin");
477
+ }
478
+ static isAvailable() {
479
+ return typeof window !== "undefined" && !!window.okxwallet?.bitcoin;
480
+ }
481
+ get icon() {
482
+ return "https://static.okx.com/cdn/assets/imgs/247/58E63FEA47A2B7D7.png";
483
+ }
484
+ async connect() {
485
+ const okx = window.okxwallet?.bitcoin;
486
+ if (!okx) {
487
+ throw new Error("OKX wallet is not installed");
488
+ }
489
+ const { address } = await okx.connect();
490
+ if (!address) return void 0;
491
+ this.walletProvider = new OKXWalletProvider(okx, address);
492
+ return {
493
+ address,
494
+ xChainType: "BITCOIN"
495
+ };
496
+ }
497
+ async disconnect() {
498
+ this.walletProvider = void 0;
499
+ }
500
+ getWalletProvider() {
501
+ return this.walletProvider;
502
+ }
503
+ recreateWalletProvider(xAccount) {
504
+ const okx = window.okxwallet?.bitcoin;
505
+ if (!okx || !xAccount.address) return void 0;
506
+ return new OKXWalletProvider(okx, xAccount.address);
507
+ }
508
+ };
180
509
  var hyper = /* @__PURE__ */ defineChain({
181
510
  id: 999,
182
511
  name: "HyperEVM",
@@ -336,117 +665,6 @@ var EvmXConnector = class extends XConnector {
336
665
  return this.connector.icon;
337
666
  }
338
667
  };
339
- var IconSdk = "default" in IconSdkRaw.default ? IconSdkRaw.default : IconSdkRaw;
340
- var { IconService: IconServiceConstructor, Builder: IconBuilder, Converter: IconConverter } = IconSdk;
341
- var CHAIN_INFO = {
342
- [1 /* MAINNET */]: {
343
- APIEndpoint: "https://ctz.solidwallet.io/api/v3"}
344
- };
345
- var IconXService = class _IconXService extends XService {
346
- constructor() {
347
- super("ICON");
348
- this.iconService = new IconServiceConstructor(
349
- new IconServiceConstructor.HttpProvider(CHAIN_INFO[1 /* MAINNET */].APIEndpoint)
350
- );
351
- }
352
- static getInstance() {
353
- if (!_IconXService.instance) {
354
- _IconXService.instance = new _IconXService();
355
- }
356
- return _IconXService.instance;
357
- }
358
- async getAggregateData(requireSuccess, calls) {
359
- const rawTx = new IconBuilder.CallBuilder().to("cxa4aa9185e23558cff990f494c1fd2845f6cbf741").method("tryAggregate").params({ requireSuccess: IconConverter.toHex(requireSuccess ? 1 : 0), calls }).build();
360
- try {
361
- const result = await this.iconService.call(rawTx).execute();
362
- const aggs = result["returnData"];
363
- const data = aggs.map((agg) => {
364
- if (agg["success"] === "0x0") {
365
- return null;
366
- }
367
- return agg["returnData"];
368
- });
369
- return data;
370
- } catch (err) {
371
- console.error(err);
372
- return Array(calls.length).fill(null);
373
- }
374
- }
375
- async getBalances(address, xTokens) {
376
- if (!address) return {};
377
- const balances = {};
378
- const nativeXToken = xTokens.find((xToken) => isNativeToken(xToken));
379
- const nonNativeXTokens = xTokens.filter((xToken) => !isNativeToken(xToken));
380
- if (nativeXToken) {
381
- const balance = await this.iconService.getBalance(address).execute();
382
- balances[nativeXToken.address] = BigInt(balance.toFixed());
383
- }
384
- const cds = nonNativeXTokens.map((token) => {
385
- return {
386
- target: token.address,
387
- method: "balanceOf",
388
- params: [address]
389
- };
390
- });
391
- const data = await this.getAggregateData(
392
- false,
393
- cds.filter((cd) => cd.target.startsWith("cx"))
394
- );
395
- return nonNativeXTokens.reduce((agg, token, idx) => {
396
- const balance = data[idx];
397
- balances[token.address] = BigInt(balance);
398
- return agg;
399
- }, balances);
400
- }
401
- };
402
-
403
- // src/xchains/icon/iconex/index.tsx
404
- var ICONEX_RELAY_RESPONSE = "ICONEX_RELAY_RESPONSE";
405
- var ICONEX_RELAY_REQUEST = "ICONEX_RELAY_REQUEST";
406
- var request = (event) => {
407
- return new Promise((resolve, reject) => {
408
- const handler = (evt) => {
409
- window.removeEventListener(ICONEX_RELAY_RESPONSE, handler);
410
- resolve(evt.detail);
411
- };
412
- window.addEventListener(ICONEX_RELAY_RESPONSE, handler);
413
- window.dispatchEvent(
414
- new CustomEvent(ICONEX_RELAY_REQUEST, {
415
- detail: event
416
- })
417
- );
418
- });
419
- };
420
-
421
- // src/xchains/icon/IconHanaXConnector.ts
422
- var IconHanaXConnector = class extends XConnector {
423
- constructor() {
424
- super("ICON", "Hana Wallet", "hana");
425
- }
426
- async connect() {
427
- const { hanaWallet } = window;
428
- if (window && !hanaWallet && !hanaWallet?.isAvailable) {
429
- window.open("https://chromewebstore.google.com/detail/hana-wallet/jfdlamikmbghhapbgfoogdffldioobgl", "_blank");
430
- return;
431
- }
432
- const detail = await request({
433
- type: "REQUEST_ADDRESS" /* REQUEST_ADDRESS */
434
- });
435
- if (detail?.type === "RESPONSE_ADDRESS" /* RESPONSE_ADDRESS */) {
436
- return {
437
- address: detail?.payload,
438
- xChainType: this.xChainType
439
- };
440
- }
441
- return void 0;
442
- }
443
- async disconnect() {
444
- console.log("HanaIconXConnector disconnected");
445
- }
446
- get icon() {
447
- return "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/hana.svg";
448
- }
449
- };
450
668
  var InjectiveXService = class _InjectiveXService extends XService {
451
669
  constructor() {
452
670
  super("INJECTIVE");
@@ -568,7 +786,7 @@ var SolanaXService = class _SolanaXService extends XService {
568
786
  if (!address) return BigInt(0);
569
787
  const connection = this.connection;
570
788
  if (!connection) {
571
- throw new Error("Connection is not initialized");
789
+ return BigInt(0);
572
790
  }
573
791
  try {
574
792
  if (isNativeToken(xToken)) {
@@ -578,29 +796,9 @@ var SolanaXService = class _SolanaXService extends XService {
578
796
  const tokenAccountPubkey = getAssociatedTokenAddressSync(new PublicKey(xToken.address), new PublicKey(address));
579
797
  const tokenAccount = await getAccount(connection, tokenAccountPubkey);
580
798
  return BigInt(tokenAccount.amount);
581
- } catch (e) {
582
- console.log("error", e);
799
+ } catch {
800
+ return BigInt(0);
583
801
  }
584
- return BigInt(0);
585
- }
586
- };
587
-
588
- // src/xchains/solana/SolanaXConnector.ts
589
- var SolanaXConnector = class extends XConnector {
590
- constructor(wallet) {
591
- super("SOLANA", wallet?.adapter.name, wallet?.adapter.name);
592
- this.wallet = wallet;
593
- }
594
- getXService() {
595
- return SolanaXService.getInstance();
596
- }
597
- async connect() {
598
- return;
599
- }
600
- async disconnect() {
601
- }
602
- get icon() {
603
- return this.wallet?.adapter.icon;
604
802
  }
605
803
  };
606
804
  var CustomSorobanServer = class extends SorobanRpc.Server {
@@ -844,9 +1042,122 @@ var SuiXConnector = class extends XConnector {
844
1042
  return this.wallet?.icon;
845
1043
  }
846
1044
  };
1045
+ var IconSdk = "default" in IconSdkRaw.default ? IconSdkRaw.default : IconSdkRaw;
1046
+ var { IconService: IconServiceConstructor, Builder: IconBuilder, Converter: IconConverter } = IconSdk;
1047
+ var CHAIN_INFO = {
1048
+ [1 /* MAINNET */]: {
1049
+ APIEndpoint: "https://ctz.solidwallet.io/api/v3"}
1050
+ };
1051
+ var IconXService = class _IconXService extends XService {
1052
+ constructor() {
1053
+ super("ICON");
1054
+ this.iconService = new IconServiceConstructor(
1055
+ new IconServiceConstructor.HttpProvider(CHAIN_INFO[1 /* MAINNET */].APIEndpoint)
1056
+ );
1057
+ }
1058
+ static getInstance() {
1059
+ if (!_IconXService.instance) {
1060
+ _IconXService.instance = new _IconXService();
1061
+ }
1062
+ return _IconXService.instance;
1063
+ }
1064
+ async getAggregateData(requireSuccess, calls) {
1065
+ const rawTx = new IconBuilder.CallBuilder().to("cxa4aa9185e23558cff990f494c1fd2845f6cbf741").method("tryAggregate").params({ requireSuccess: IconConverter.toHex(requireSuccess ? 1 : 0), calls }).build();
1066
+ try {
1067
+ const result = await this.iconService.call(rawTx).execute();
1068
+ const aggs = result["returnData"];
1069
+ const data = aggs.map((agg) => {
1070
+ if (agg["success"] === "0x0") {
1071
+ return null;
1072
+ }
1073
+ return agg["returnData"];
1074
+ });
1075
+ return data;
1076
+ } catch (err) {
1077
+ console.error(err);
1078
+ return Array(calls.length).fill(null);
1079
+ }
1080
+ }
1081
+ async getBalances(address, xTokens) {
1082
+ if (!address) return {};
1083
+ const balances = {};
1084
+ const nativeXToken = xTokens.find((xToken) => isNativeToken(xToken));
1085
+ const nonNativeXTokens = xTokens.filter((xToken) => !isNativeToken(xToken));
1086
+ if (nativeXToken) {
1087
+ const balance = await this.iconService.getBalance(address).execute();
1088
+ balances[nativeXToken.address] = BigInt(balance.toFixed());
1089
+ }
1090
+ const cds = nonNativeXTokens.map((token) => {
1091
+ return {
1092
+ target: token.address,
1093
+ method: "balanceOf",
1094
+ params: [address]
1095
+ };
1096
+ });
1097
+ const data = await this.getAggregateData(
1098
+ false,
1099
+ cds.filter((cd) => cd.target.startsWith("cx"))
1100
+ );
1101
+ return nonNativeXTokens.reduce((agg, token, idx) => {
1102
+ const balance = data[idx];
1103
+ balances[token.address] = BigInt(balance);
1104
+ return agg;
1105
+ }, balances);
1106
+ }
1107
+ };
1108
+
1109
+ // src/xchains/icon/iconex/index.tsx
1110
+ var ICONEX_RELAY_RESPONSE = "ICONEX_RELAY_RESPONSE";
1111
+ var ICONEX_RELAY_REQUEST = "ICONEX_RELAY_REQUEST";
1112
+ var request = (event) => {
1113
+ return new Promise((resolve, reject) => {
1114
+ const handler = (evt) => {
1115
+ window.removeEventListener(ICONEX_RELAY_RESPONSE, handler);
1116
+ resolve(evt.detail);
1117
+ };
1118
+ window.addEventListener(ICONEX_RELAY_RESPONSE, handler);
1119
+ window.dispatchEvent(
1120
+ new CustomEvent(ICONEX_RELAY_REQUEST, {
1121
+ detail: event
1122
+ })
1123
+ );
1124
+ });
1125
+ };
1126
+
1127
+ // src/xchains/icon/IconHanaXConnector.ts
1128
+ var IconHanaXConnector = class extends XConnector {
1129
+ constructor() {
1130
+ super("ICON", "Hana Wallet", "hana");
1131
+ }
1132
+ async connect() {
1133
+ const { hanaWallet } = window;
1134
+ if (window && !hanaWallet && !hanaWallet?.isAvailable) {
1135
+ window.open("https://chromewebstore.google.com/detail/hana-wallet/jfdlamikmbghhapbgfoogdffldioobgl", "_blank");
1136
+ return;
1137
+ }
1138
+ const detail = await request({
1139
+ type: "REQUEST_ADDRESS" /* REQUEST_ADDRESS */
1140
+ });
1141
+ if (detail?.type === "RESPONSE_ADDRESS" /* RESPONSE_ADDRESS */) {
1142
+ return {
1143
+ address: detail?.payload,
1144
+ xChainType: this.xChainType
1145
+ };
1146
+ }
1147
+ return void 0;
1148
+ }
1149
+ async disconnect() {
1150
+ console.log("HanaIconXConnector disconnected");
1151
+ }
1152
+ get icon() {
1153
+ return "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/hana.svg";
1154
+ }
1155
+ };
1156
+
1157
+ // src/useXWagmiStore.ts
847
1158
  var initXServices = () => {
848
1159
  const xServices = {};
849
- ["EVM", "INJECTIVE", "STELLAR", "SUI", "SOLANA", "ICON", "NEAR"].forEach((key) => {
1160
+ ["EVM", "BITCOIN", "INJECTIVE", "STELLAR", "SUI", "SOLANA", "ICON", "NEAR"].forEach((key) => {
850
1161
  const xChainType = key;
851
1162
  switch (xChainType) {
852
1163
  // EVM, SUI, Solana wallet connectors are supported by their own sdks. wagmi, @mysten/dapp-kit, @solana/wallet-adapter-react.
@@ -862,6 +1173,14 @@ var initXServices = () => {
862
1173
  xServices[xChainType] = SolanaXService.getInstance();
863
1174
  xServices[xChainType].setXConnectors([]);
864
1175
  break;
1176
+ case "BITCOIN":
1177
+ xServices[xChainType] = BitcoinXService.getInstance();
1178
+ xServices[xChainType].setXConnectors([
1179
+ new UnisatXConnector(),
1180
+ new XverseXConnector(),
1181
+ new OKXXConnector()
1182
+ ]);
1183
+ break;
865
1184
  // Injective, Stellar, Icon wallet connectors are supported by sodax wallet-sdk-react sdk.
866
1185
  case "INJECTIVE":
867
1186
  xServices[xChainType] = InjectiveXService.getInstance();
@@ -1074,6 +1393,25 @@ function useXConnect() {
1074
1393
  }
1075
1394
  });
1076
1395
  }
1396
+
1397
+ // src/xchains/solana/SolanaXConnector.ts
1398
+ var SolanaXConnector = class extends XConnector {
1399
+ constructor(wallet) {
1400
+ super("SOLANA", wallet?.adapter.name, wallet?.adapter.name);
1401
+ this.wallet = wallet;
1402
+ }
1403
+ getXService() {
1404
+ return SolanaXService.getInstance();
1405
+ }
1406
+ async connect() {
1407
+ return;
1408
+ }
1409
+ async disconnect() {
1410
+ }
1411
+ get icon() {
1412
+ return this.wallet?.adapter.icon;
1413
+ }
1414
+ };
1077
1415
  var useStellarXConnectors = () => {
1078
1416
  const xService = useXService("STELLAR");
1079
1417
  return useQuery({
@@ -1220,8 +1558,7 @@ function useXBalances({
1220
1558
  const balances = await xService.getBalances(address, xTokens);
1221
1559
  return balances;
1222
1560
  },
1223
- enabled: !!xService,
1224
- placeholderData: keepPreviousData,
1561
+ enabled: !!xService && !!address && (xTokens?.length ?? 0) > 0,
1225
1562
  refetchInterval: 5e3
1226
1563
  });
1227
1564
  }
@@ -1288,6 +1625,7 @@ function useWalletProvider(spokeChainId) {
1288
1625
  const { data: evmWalletClient } = useWalletClient();
1289
1626
  const xService = useXService(getXChainType(spokeChainId));
1290
1627
  const xAccount = useXAccount(spokeChainId);
1628
+ const xConnection = useXConnection(xChainType);
1291
1629
  return useMemo(() => {
1292
1630
  switch (xChainType) {
1293
1631
  case "EVM": {
@@ -1351,9 +1689,15 @@ function useWalletProvider(spokeChainId) {
1351
1689
  }
1352
1690
  return new SolanaWalletProvider({
1353
1691
  wallet: solanaXService.wallet,
1354
- connection: solanaXService.connection
1692
+ endpoint: solanaXService.connection.rpcEndpoint
1355
1693
  });
1356
1694
  }
1695
+ case "BITCOIN": {
1696
+ if (!xConnection?.xConnectorId) return void 0;
1697
+ const connector = BitcoinXService.getInstance().getXConnectorById(xConnection.xConnectorId);
1698
+ if (!connector) return void 0;
1699
+ return connector.recreateWalletProvider(xConnection.xAccount);
1700
+ }
1357
1701
  case "NEAR": {
1358
1702
  const nearXService = xService;
1359
1703
  if (!nearXService.walletSelector) {
@@ -1364,7 +1708,7 @@ function useWalletProvider(spokeChainId) {
1364
1708
  default:
1365
1709
  return void 0;
1366
1710
  }
1367
- }, [xChainType, evmPublicClient, evmWalletClient, xService, xAccount]);
1711
+ }, [xChainType, evmPublicClient, evmWalletClient, xService, xAccount, xConnection]);
1368
1712
  }
1369
1713
  function useXSignMessage() {
1370
1714
  const { signMessage } = useWallet();
@@ -1420,10 +1764,13 @@ function useXSignMessage() {
1420
1764
  }
1421
1765
  });
1422
1766
  }
1423
- function useAnchorProvider() {
1424
- const { connection } = useConnection();
1425
- const wallet = useWallet();
1426
- return new AnchorProvider(connection, wallet, { commitment: "confirmed" });
1767
+
1768
+ // src/xchains/bitcoin/useBitcoinXConnectors.ts
1769
+ function useBitcoinXConnectors() {
1770
+ const xService = useXService("BITCOIN");
1771
+ return useMemo(() => {
1772
+ return xService?.getXConnectors() || [];
1773
+ }, [xService]);
1427
1774
  }
1428
1775
  var Hydrate = () => {
1429
1776
  const suiClient = useSuiClient();
@@ -1446,7 +1793,6 @@ var Hydrate = () => {
1446
1793
  }, [suiAccount]);
1447
1794
  const { connection: solanaConnection } = useConnection();
1448
1795
  const solanaWallet = useWallet();
1449
- const solanaProvider = useAnchorProvider();
1450
1796
  useEffect(() => {
1451
1797
  if (solanaConnection) {
1452
1798
  SolanaXService.getInstance().connection = solanaConnection;
@@ -1457,11 +1803,6 @@ var Hydrate = () => {
1457
1803
  SolanaXService.getInstance().wallet = solanaWallet;
1458
1804
  }
1459
1805
  }, [solanaWallet]);
1460
- useEffect(() => {
1461
- if (solanaProvider) {
1462
- SolanaXService.getInstance().provider = solanaProvider;
1463
- }
1464
- }, [solanaProvider]);
1465
1806
  const wagmiConfig = useConfig();
1466
1807
  useEffect(() => {
1467
1808
  if (wagmiConfig) {
@@ -1522,7 +1863,7 @@ var SodaxWalletProvider = ({ children, rpcConfig }) => {
1522
1863
  return createWagmiConfig(rpcConfig);
1523
1864
  }, [rpcConfig]);
1524
1865
  const wallets = useMemo(() => [new UnsafeBurnerWalletAdapter()], []);
1525
- return /* @__PURE__ */ React2.createElement(QueryClientProvider, { client: queryClient }, /* @__PURE__ */ React2.createElement(WagmiProvider, { reconnectOnMount: false, config: wagmiConfig }, /* @__PURE__ */ React2.createElement(SuiClientProvider, { networks: { mainnet: { url: getFullnodeUrl("mainnet") } }, defaultNetwork: "mainnet" }, /* @__PURE__ */ React2.createElement(WalletProvider, { autoConnect: true }, /* @__PURE__ */ React2.createElement(ConnectionProvider, { endpoint: rpcConfig["solana"] ?? "" }, /* @__PURE__ */ React2.createElement(WalletProvider$1, { wallets, autoConnect: true }, /* @__PURE__ */ React2.createElement(Hydrate, null), children))))));
1866
+ return /* @__PURE__ */ React2.createElement(QueryClientProvider, { client: queryClient }, /* @__PURE__ */ React2.createElement(WagmiProvider, { reconnectOnMount: false, config: wagmiConfig }, /* @__PURE__ */ React2.createElement(SuiClientProvider, { networks: { mainnet: { url: getFullnodeUrl("mainnet") } }, defaultNetwork: "mainnet" }, /* @__PURE__ */ React2.createElement(WalletProvider, { autoConnect: true }, /* @__PURE__ */ React2.createElement(ConnectionProvider, { endpoint: rpcConfig["solana"] ?? "https://api.mainnet-beta.solana.com" }, /* @__PURE__ */ React2.createElement(WalletProvider$1, { wallets, autoConnect: true }, /* @__PURE__ */ React2.createElement(Hydrate, null), children))))));
1526
1867
  };
1527
1868
  reconnectIcon();
1528
1869
  reconnectStellar();
@@ -1537,6 +1878,6 @@ var WalletId = /* @__PURE__ */ ((WalletId2) => {
1537
1878
  return WalletId2;
1538
1879
  })(WalletId || {});
1539
1880
 
1540
- export { EvmXConnector, EvmXService, IconHanaXConnector, IconXService, InjectiveKelprXConnector, InjectiveMetamaskXConnector, InjectiveXService, SodaxWalletProvider, SolanaXConnector, SolanaXService, StellarWalletsKitXConnector, StellarXService, SuiXConnector, SuiXService, WalletId, XConnector, XService, getWagmiChainId, getXChainType, getXService, isNativeToken, switchEthereumChain, useEvmSwitchChain, useWalletProvider, useXAccount, useXAccounts, useXBalances, useXConnect, useXConnection, useXConnectors, useXDisconnect, useXService, useXSignMessage, useXWagmiStore };
1881
+ export { BitcoinXConnector, BitcoinXService, EvmXConnector, EvmXService, IconHanaXConnector, IconXService, InjectiveKelprXConnector, InjectiveMetamaskXConnector, InjectiveXService, OKXXConnector, SodaxWalletProvider, SolanaXConnector, SolanaXService, StellarWalletsKitXConnector, StellarXService, SuiXConnector, SuiXService, UnisatXConnector, WalletId, XConnector, XService, XverseXConnector, getWagmiChainId, getXChainType, getXService, isNativeToken, switchEthereumChain, useBitcoinXConnectors, useEvmSwitchChain, useWalletProvider, useXAccount, useXAccounts, useXBalances, useXConnect, useXConnection, useXConnectors, useXDisconnect, useXService, useXSignMessage, useXWagmiStore };
1541
1882
  //# sourceMappingURL=index.mjs.map
1542
1883
  //# sourceMappingURL=index.mjs.map