@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.cjs CHANGED
@@ -3,11 +3,17 @@
3
3
  var types = require('@sodax/types');
4
4
  var nearConnect = require('@hot-labs/near-connect');
5
5
  var nearApiJs = require('near-api-js');
6
+ var satsConnect = require('sats-connect');
7
+ var React2 = require('react');
8
+ var dappKit = require('@mysten/dapp-kit');
9
+ var walletAdapterReact = require('@solana/wallet-adapter-react');
10
+ var wagmi = require('wagmi');
11
+ var zustand = require('zustand');
12
+ var middleware = require('zustand/middleware');
13
+ var immer = require('zustand/middleware/immer');
6
14
  var viem = require('viem');
7
15
  var actions = require('wagmi/actions');
8
- var wagmi = require('wagmi');
9
16
  var chains = require('wagmi/chains');
10
- var IconSdkRaw = require('icon-sdk-js');
11
17
  var networks = require('@injectivelabs/networks');
12
18
  var sdkTs = require('@injectivelabs/sdk-ts');
13
19
  var tsTypes = require('@injectivelabs/ts-types');
@@ -19,18 +25,12 @@ var web3_js = require('@solana/web3.js');
19
25
  var splToken = require('@solana/spl-token');
20
26
  var stellarWalletsKit = require('@creit.tech/stellar-wallets-kit');
21
27
  var StellarSdk = require('@stellar/stellar-sdk');
22
- var React2 = require('react');
23
- var dappKit = require('@mysten/dapp-kit');
24
- var walletAdapterReact = require('@solana/wallet-adapter-react');
25
- var zustand = require('zustand');
26
- var middleware = require('zustand/middleware');
27
- var immer = require('zustand/middleware/immer');
28
+ var IconSdkRaw = require('icon-sdk-js');
28
29
  var reactQuery = require('@tanstack/react-query');
29
30
  var chains$1 = require('viem/chains');
30
31
  var walletSdkCore = require('@sodax/wallet-sdk-core');
31
32
  var client = require('@mysten/sui/client');
32
33
  var walletAdapterWallets = require('@solana/wallet-adapter-wallets');
33
- var anchor = require('@coral-xyz/anchor');
34
34
 
35
35
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
36
36
 
@@ -52,9 +52,9 @@ function _interopNamespace(e) {
52
52
  return Object.freeze(n);
53
53
  }
54
54
 
55
- var IconSdkRaw__namespace = /*#__PURE__*/_interopNamespace(IconSdkRaw);
56
- var StellarSdk__namespace = /*#__PURE__*/_interopNamespace(StellarSdk);
57
55
  var React2__default = /*#__PURE__*/_interopDefault(React2);
56
+ var StellarSdk__namespace = /*#__PURE__*/_interopNamespace(StellarSdk);
57
+ var IconSdkRaw__namespace = /*#__PURE__*/_interopNamespace(IconSdkRaw);
58
58
 
59
59
  // src/actions/getXChainType.ts
60
60
  function getXChainType(xChainId) {
@@ -150,6 +150,8 @@ var NearXService = class _NearXService extends XService {
150
150
  // src/actions/getXService.ts
151
151
  function getXService(xChainType) {
152
152
  switch (xChainType) {
153
+ case "BITCOIN":
154
+ return BitcoinXService.getInstance();
153
155
  case "EVM":
154
156
  return EvmXService.getInstance();
155
157
  case "SUI":
@@ -194,14 +196,341 @@ var isNativeToken = (xToken) => {
194
196
  "hx0000000000000000000000000000000000000000",
195
197
  "11111111111111111111111111111111",
196
198
  // solana
197
- "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA"
198
- // stellar,
199
+ "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA",
200
+ // stellar
201
+ "0:0"
202
+ // bitcoin
199
203
  ];
200
204
  return nativeAddresses.includes(xToken.address);
201
205
  };
202
206
  var getWagmiChainId = (xChainId) => {
203
207
  return types.baseChainInfo[xChainId].chainId;
204
208
  };
209
+
210
+ // src/xchains/bitcoin/BitcoinXService.ts
211
+ var BitcoinXService = class _BitcoinXService extends XService {
212
+ constructor(rpcUrl = "https://mempool.space/api") {
213
+ super("BITCOIN");
214
+ this.rpcUrl = rpcUrl;
215
+ }
216
+ static getInstance(rpcUrl) {
217
+ if (!_BitcoinXService.instance) {
218
+ _BitcoinXService.instance = new _BitcoinXService(rpcUrl);
219
+ } else if (rpcUrl && rpcUrl !== _BitcoinXService.instance.rpcUrl) {
220
+ _BitcoinXService.instance.rpcUrl = rpcUrl;
221
+ }
222
+ return _BitcoinXService.instance;
223
+ }
224
+ async getBalance(address, xToken) {
225
+ if (!address) return 0n;
226
+ try {
227
+ if (isNativeToken(xToken)) {
228
+ const response = await fetch(`${this.rpcUrl}/address/${address}/utxo`);
229
+ if (!response.ok) return 0n;
230
+ const utxos = await response.json();
231
+ const totalBalance = utxos.reduce((sum, utxo) => sum + utxo.value, 0);
232
+ return BigInt(totalBalance);
233
+ }
234
+ } catch {
235
+ return 0n;
236
+ }
237
+ return 0n;
238
+ }
239
+ };
240
+
241
+ // src/xchains/bitcoin/BitcoinXConnector.ts
242
+ var BitcoinXConnector = class extends XConnector {
243
+ constructor(name, id) {
244
+ super("BITCOIN", name, id);
245
+ }
246
+ getXService() {
247
+ return BitcoinXService.getInstance();
248
+ }
249
+ };
250
+ var UnisatWalletProvider = class {
251
+ constructor(unisat, address) {
252
+ this.unisat = unisat;
253
+ this.cachedAddress = address;
254
+ }
255
+ async getWalletAddress() {
256
+ try {
257
+ const accounts = await this.unisat.getAccounts();
258
+ if (accounts[0]) this.cachedAddress = accounts[0];
259
+ } catch {
260
+ }
261
+ return this.cachedAddress;
262
+ }
263
+ async getPublicKey() {
264
+ return this.unisat.getPublicKey();
265
+ }
266
+ async getAddressType(_address) {
267
+ const address = await this.getWalletAddress();
268
+ return types.detectBitcoinAddressType(address);
269
+ }
270
+ async signTransaction(psbtBase64, finalize = false) {
271
+ const psbtHex = Buffer.from(psbtBase64, "base64").toString("hex");
272
+ const signedHex = await this.unisat.signPsbt(psbtHex, { autoFinalized: finalize });
273
+ return signedHex;
274
+ }
275
+ async signEcdsaMessage(message) {
276
+ return this.unisat.signMessage(message, "ecdsa");
277
+ }
278
+ async signBip322Message(message) {
279
+ return this.unisat.signMessage(message, "bip322-simple");
280
+ }
281
+ async sendBitcoin(toAddress, satoshis) {
282
+ if (satoshis > BigInt(Number.MAX_SAFE_INTEGER)) {
283
+ throw new Error(`Amount ${satoshis} satoshis exceeds safe integer range`);
284
+ }
285
+ return this.unisat.sendBitcoin(toAddress, Number(satoshis));
286
+ }
287
+ };
288
+ var UnisatXConnector = class extends BitcoinXConnector {
289
+ constructor() {
290
+ super("Unisat", "unisat");
291
+ }
292
+ static isAvailable() {
293
+ return typeof window !== "undefined" && !!window.unisat;
294
+ }
295
+ get icon() {
296
+ return "https://avatars.githubusercontent.com/u/125119198?s=200&v=4";
297
+ }
298
+ async connect() {
299
+ if (!window.unisat) {
300
+ throw new Error("Unisat wallet is not installed");
301
+ }
302
+ const accounts = await window.unisat.requestAccounts();
303
+ const address = accounts[0];
304
+ if (!address) return void 0;
305
+ this.walletProvider = new UnisatWalletProvider(window.unisat, address);
306
+ return {
307
+ address,
308
+ xChainType: "BITCOIN"
309
+ };
310
+ }
311
+ async disconnect() {
312
+ this.walletProvider = void 0;
313
+ }
314
+ getWalletProvider() {
315
+ return this.walletProvider;
316
+ }
317
+ recreateWalletProvider(xAccount) {
318
+ if (!window.unisat || !xAccount.address) return void 0;
319
+ return new UnisatWalletProvider(window.unisat, xAccount.address);
320
+ }
321
+ };
322
+ var XverseWalletProvider = class {
323
+ constructor(address, publicKey) {
324
+ this.address = address;
325
+ this.publicKey = publicKey;
326
+ }
327
+ async getWalletAddress() {
328
+ return this.address;
329
+ }
330
+ async getPublicKey() {
331
+ return this.publicKey;
332
+ }
333
+ async getAddressType(_address) {
334
+ return types.detectBitcoinAddressType(this.address);
335
+ }
336
+ /**
337
+ * Parse a base64-encoded PSBT to count the number of inputs.
338
+ * Reads the unsigned transaction from the PSBT global section.
339
+ */
340
+ countPsbtInputs(psbtBase64) {
341
+ const data = Buffer.from(psbtBase64, "base64");
342
+ let offset = 5;
343
+ const keyLen = data[offset++] ?? 0;
344
+ if (keyLen !== 1 || data[offset++] !== 0) {
345
+ return 1;
346
+ }
347
+ const firstByte = data[offset++] ?? 0;
348
+ if (firstByte === 253) offset += 2;
349
+ else if (firstByte === 254) offset += 4;
350
+ else if (firstByte === 255) offset += 8;
351
+ offset += 4;
352
+ const inputByte = data[offset] ?? 0;
353
+ if (inputByte < 253) return inputByte;
354
+ return 1;
355
+ }
356
+ async signTransaction(psbtBase64, finalize = false) {
357
+ const { request: request2 } = await import('sats-connect');
358
+ const inputCount = this.countPsbtInputs(psbtBase64);
359
+ const signingIndexes = Array.from({ length: inputCount }, (_, i) => i);
360
+ const response = await request2("signPsbt", {
361
+ psbt: psbtBase64,
362
+ broadcast: false,
363
+ signInputs: {
364
+ [this.address]: signingIndexes
365
+ }
366
+ });
367
+ if (response.status === "error") {
368
+ throw new Error(response.error?.message || "Xverse PSBT signing failed");
369
+ }
370
+ const result = response.result;
371
+ if (finalize) {
372
+ return Buffer.from(result.psbt, "base64").toString("hex");
373
+ }
374
+ return result.psbt;
375
+ }
376
+ async signEcdsaMessage(message) {
377
+ const { request: request2 } = await import('sats-connect');
378
+ const response = await request2("signMessage", {
379
+ address: this.address,
380
+ message,
381
+ protocol: satsConnect.MessageSigningProtocols.ECDSA
382
+ });
383
+ if (response.status === "error") {
384
+ throw new Error(response.error?.message || "Xverse ECDSA signing failed");
385
+ }
386
+ return response.result.signature;
387
+ }
388
+ async signBip322Message(message) {
389
+ const { request: request2 } = await import('sats-connect');
390
+ const response = await request2("signMessage", {
391
+ address: this.address,
392
+ message,
393
+ protocol: satsConnect.MessageSigningProtocols.BIP322
394
+ });
395
+ if (response.status === "error") {
396
+ throw new Error(response.error?.message || "Xverse BIP322 signing failed");
397
+ }
398
+ return response.result.signature;
399
+ }
400
+ async sendBitcoin(toAddress, satoshis) {
401
+ const { request: request2 } = await import('sats-connect');
402
+ const response = await request2("sendTransfer", {
403
+ recipients: [
404
+ {
405
+ address: toAddress,
406
+ amount: Number(satoshis)
407
+ }
408
+ ]
409
+ });
410
+ if (response.status === "error") {
411
+ throw new Error(response.error?.message || "Xverse sendTransfer failed");
412
+ }
413
+ return response.result.txid;
414
+ }
415
+ };
416
+ var XverseXConnector = class _XverseXConnector extends BitcoinXConnector {
417
+ constructor() {
418
+ super("Xverse", "xverse");
419
+ }
420
+ static isAvailable() {
421
+ return typeof window !== "undefined" && !!window.BitcoinProvider;
422
+ }
423
+ get icon() {
424
+ return "https://cdn.brandfetch.io/iddzGN5Rcv/w/400/h/400/theme/dark/icon.jpeg?c=1bxid64Mup7aczewSAYMX&t=1771902357797";
425
+ }
426
+ async connect() {
427
+ if (!_XverseXConnector.isAvailable()) {
428
+ throw new Error("Xverse wallet is not installed");
429
+ }
430
+ const { request: request2 } = await import('sats-connect');
431
+ const response = await request2("getAccounts", {
432
+ purposes: [satsConnect.AddressPurpose.Payment],
433
+ message: "Connect to Sodax"
434
+ });
435
+ if (response.status === "error") {
436
+ throw new Error(response.error?.message || "Xverse connection failed");
437
+ }
438
+ const accounts = response.result;
439
+ const paymentAccount = accounts.find((a) => a.purpose === satsConnect.AddressPurpose.Payment) || accounts[0];
440
+ if (!paymentAccount) return void 0;
441
+ this.walletProvider = new XverseWalletProvider(
442
+ paymentAccount.address,
443
+ paymentAccount.publicKey
444
+ );
445
+ return {
446
+ address: paymentAccount.address,
447
+ publicKey: paymentAccount.publicKey,
448
+ xChainType: "BITCOIN"
449
+ };
450
+ }
451
+ async disconnect() {
452
+ this.walletProvider = void 0;
453
+ }
454
+ getWalletProvider() {
455
+ return this.walletProvider;
456
+ }
457
+ recreateWalletProvider(xAccount) {
458
+ if (!xAccount.address || !xAccount.publicKey) return void 0;
459
+ return new XverseWalletProvider(xAccount.address, xAccount.publicKey);
460
+ }
461
+ };
462
+ var OKXWalletProvider = class {
463
+ constructor(okx, address) {
464
+ this.okx = okx;
465
+ this.cachedAddress = address;
466
+ }
467
+ async getWalletAddress() {
468
+ try {
469
+ const accounts = await this.okx.getAccounts();
470
+ if (accounts[0]) this.cachedAddress = accounts[0];
471
+ } catch {
472
+ }
473
+ return this.cachedAddress;
474
+ }
475
+ async getPublicKey() {
476
+ return this.okx.getPublicKey();
477
+ }
478
+ async getAddressType(_address) {
479
+ const address = await this.getWalletAddress();
480
+ return types.detectBitcoinAddressType(address);
481
+ }
482
+ async signTransaction(psbtBase64, finalize = false) {
483
+ const psbtHex = Buffer.from(psbtBase64, "base64").toString("hex");
484
+ return this.okx.signPsbt(psbtHex, { autoFinalized: finalize });
485
+ }
486
+ async signEcdsaMessage(message) {
487
+ return this.okx.signMessage(message, "ecdsa");
488
+ }
489
+ async signBip322Message(message) {
490
+ return this.okx.signMessage(message, "bip322-simple");
491
+ }
492
+ async sendBitcoin(toAddress, satoshis) {
493
+ if (satoshis > BigInt(Number.MAX_SAFE_INTEGER)) {
494
+ throw new Error(`Amount ${satoshis} satoshis exceeds safe integer range`);
495
+ }
496
+ return this.okx.sendBitcoin(toAddress, Number(satoshis));
497
+ }
498
+ };
499
+ var OKXXConnector = class extends BitcoinXConnector {
500
+ constructor() {
501
+ super("OKX Wallet", "okx-bitcoin");
502
+ }
503
+ static isAvailable() {
504
+ return typeof window !== "undefined" && !!window.okxwallet?.bitcoin;
505
+ }
506
+ get icon() {
507
+ return "https://static.okx.com/cdn/assets/imgs/247/58E63FEA47A2B7D7.png";
508
+ }
509
+ async connect() {
510
+ const okx = window.okxwallet?.bitcoin;
511
+ if (!okx) {
512
+ throw new Error("OKX wallet is not installed");
513
+ }
514
+ const { address } = await okx.connect();
515
+ if (!address) return void 0;
516
+ this.walletProvider = new OKXWalletProvider(okx, address);
517
+ return {
518
+ address,
519
+ xChainType: "BITCOIN"
520
+ };
521
+ }
522
+ async disconnect() {
523
+ this.walletProvider = void 0;
524
+ }
525
+ getWalletProvider() {
526
+ return this.walletProvider;
527
+ }
528
+ recreateWalletProvider(xAccount) {
529
+ const okx = window.okxwallet?.bitcoin;
530
+ if (!okx || !xAccount.address) return void 0;
531
+ return new OKXWalletProvider(okx, xAccount.address);
532
+ }
533
+ };
205
534
  var hyper = /* @__PURE__ */ viem.defineChain({
206
535
  id: 999,
207
536
  name: "HyperEVM",
@@ -361,117 +690,6 @@ var EvmXConnector = class extends XConnector {
361
690
  return this.connector.icon;
362
691
  }
363
692
  };
364
- var IconSdk = "default" in IconSdkRaw__namespace.default ? IconSdkRaw__namespace.default : IconSdkRaw__namespace;
365
- var { IconService: IconServiceConstructor, Builder: IconBuilder, Converter: IconConverter } = IconSdk;
366
- var CHAIN_INFO = {
367
- [1 /* MAINNET */]: {
368
- APIEndpoint: "https://ctz.solidwallet.io/api/v3"}
369
- };
370
- var IconXService = class _IconXService extends XService {
371
- constructor() {
372
- super("ICON");
373
- this.iconService = new IconServiceConstructor(
374
- new IconServiceConstructor.HttpProvider(CHAIN_INFO[1 /* MAINNET */].APIEndpoint)
375
- );
376
- }
377
- static getInstance() {
378
- if (!_IconXService.instance) {
379
- _IconXService.instance = new _IconXService();
380
- }
381
- return _IconXService.instance;
382
- }
383
- async getAggregateData(requireSuccess, calls) {
384
- const rawTx = new IconBuilder.CallBuilder().to("cxa4aa9185e23558cff990f494c1fd2845f6cbf741").method("tryAggregate").params({ requireSuccess: IconConverter.toHex(requireSuccess ? 1 : 0), calls }).build();
385
- try {
386
- const result = await this.iconService.call(rawTx).execute();
387
- const aggs = result["returnData"];
388
- const data = aggs.map((agg) => {
389
- if (agg["success"] === "0x0") {
390
- return null;
391
- }
392
- return agg["returnData"];
393
- });
394
- return data;
395
- } catch (err) {
396
- console.error(err);
397
- return Array(calls.length).fill(null);
398
- }
399
- }
400
- async getBalances(address, xTokens) {
401
- if (!address) return {};
402
- const balances = {};
403
- const nativeXToken = xTokens.find((xToken) => isNativeToken(xToken));
404
- const nonNativeXTokens = xTokens.filter((xToken) => !isNativeToken(xToken));
405
- if (nativeXToken) {
406
- const balance = await this.iconService.getBalance(address).execute();
407
- balances[nativeXToken.address] = BigInt(balance.toFixed());
408
- }
409
- const cds = nonNativeXTokens.map((token) => {
410
- return {
411
- target: token.address,
412
- method: "balanceOf",
413
- params: [address]
414
- };
415
- });
416
- const data = await this.getAggregateData(
417
- false,
418
- cds.filter((cd) => cd.target.startsWith("cx"))
419
- );
420
- return nonNativeXTokens.reduce((agg, token, idx) => {
421
- const balance = data[idx];
422
- balances[token.address] = BigInt(balance);
423
- return agg;
424
- }, balances);
425
- }
426
- };
427
-
428
- // src/xchains/icon/iconex/index.tsx
429
- var ICONEX_RELAY_RESPONSE = "ICONEX_RELAY_RESPONSE";
430
- var ICONEX_RELAY_REQUEST = "ICONEX_RELAY_REQUEST";
431
- var request = (event) => {
432
- return new Promise((resolve, reject) => {
433
- const handler = (evt) => {
434
- window.removeEventListener(ICONEX_RELAY_RESPONSE, handler);
435
- resolve(evt.detail);
436
- };
437
- window.addEventListener(ICONEX_RELAY_RESPONSE, handler);
438
- window.dispatchEvent(
439
- new CustomEvent(ICONEX_RELAY_REQUEST, {
440
- detail: event
441
- })
442
- );
443
- });
444
- };
445
-
446
- // src/xchains/icon/IconHanaXConnector.ts
447
- var IconHanaXConnector = class extends XConnector {
448
- constructor() {
449
- super("ICON", "Hana Wallet", "hana");
450
- }
451
- async connect() {
452
- const { hanaWallet } = window;
453
- if (window && !hanaWallet && !hanaWallet?.isAvailable) {
454
- window.open("https://chromewebstore.google.com/detail/hana-wallet/jfdlamikmbghhapbgfoogdffldioobgl", "_blank");
455
- return;
456
- }
457
- const detail = await request({
458
- type: "REQUEST_ADDRESS" /* REQUEST_ADDRESS */
459
- });
460
- if (detail?.type === "RESPONSE_ADDRESS" /* RESPONSE_ADDRESS */) {
461
- return {
462
- address: detail?.payload,
463
- xChainType: this.xChainType
464
- };
465
- }
466
- return void 0;
467
- }
468
- async disconnect() {
469
- console.log("HanaIconXConnector disconnected");
470
- }
471
- get icon() {
472
- return "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/hana.svg";
473
- }
474
- };
475
693
  var InjectiveXService = class _InjectiveXService extends XService {
476
694
  constructor() {
477
695
  super("INJECTIVE");
@@ -593,7 +811,7 @@ var SolanaXService = class _SolanaXService extends XService {
593
811
  if (!address) return BigInt(0);
594
812
  const connection = this.connection;
595
813
  if (!connection) {
596
- throw new Error("Connection is not initialized");
814
+ return BigInt(0);
597
815
  }
598
816
  try {
599
817
  if (isNativeToken(xToken)) {
@@ -603,29 +821,9 @@ var SolanaXService = class _SolanaXService extends XService {
603
821
  const tokenAccountPubkey = splToken.getAssociatedTokenAddressSync(new web3_js.PublicKey(xToken.address), new web3_js.PublicKey(address));
604
822
  const tokenAccount = await splToken.getAccount(connection, tokenAccountPubkey);
605
823
  return BigInt(tokenAccount.amount);
606
- } catch (e) {
607
- console.log("error", e);
824
+ } catch {
825
+ return BigInt(0);
608
826
  }
609
- return BigInt(0);
610
- }
611
- };
612
-
613
- // src/xchains/solana/SolanaXConnector.ts
614
- var SolanaXConnector = class extends XConnector {
615
- constructor(wallet) {
616
- super("SOLANA", wallet?.adapter.name, wallet?.adapter.name);
617
- this.wallet = wallet;
618
- }
619
- getXService() {
620
- return SolanaXService.getInstance();
621
- }
622
- async connect() {
623
- return;
624
- }
625
- async disconnect() {
626
- }
627
- get icon() {
628
- return this.wallet?.adapter.icon;
629
827
  }
630
828
  };
631
829
  var CustomSorobanServer = class extends StellarSdk.SorobanRpc.Server {
@@ -869,9 +1067,122 @@ var SuiXConnector = class extends XConnector {
869
1067
  return this.wallet?.icon;
870
1068
  }
871
1069
  };
1070
+ var IconSdk = "default" in IconSdkRaw__namespace.default ? IconSdkRaw__namespace.default : IconSdkRaw__namespace;
1071
+ var { IconService: IconServiceConstructor, Builder: IconBuilder, Converter: IconConverter } = IconSdk;
1072
+ var CHAIN_INFO = {
1073
+ [1 /* MAINNET */]: {
1074
+ APIEndpoint: "https://ctz.solidwallet.io/api/v3"}
1075
+ };
1076
+ var IconXService = class _IconXService extends XService {
1077
+ constructor() {
1078
+ super("ICON");
1079
+ this.iconService = new IconServiceConstructor(
1080
+ new IconServiceConstructor.HttpProvider(CHAIN_INFO[1 /* MAINNET */].APIEndpoint)
1081
+ );
1082
+ }
1083
+ static getInstance() {
1084
+ if (!_IconXService.instance) {
1085
+ _IconXService.instance = new _IconXService();
1086
+ }
1087
+ return _IconXService.instance;
1088
+ }
1089
+ async getAggregateData(requireSuccess, calls) {
1090
+ const rawTx = new IconBuilder.CallBuilder().to("cxa4aa9185e23558cff990f494c1fd2845f6cbf741").method("tryAggregate").params({ requireSuccess: IconConverter.toHex(requireSuccess ? 1 : 0), calls }).build();
1091
+ try {
1092
+ const result = await this.iconService.call(rawTx).execute();
1093
+ const aggs = result["returnData"];
1094
+ const data = aggs.map((agg) => {
1095
+ if (agg["success"] === "0x0") {
1096
+ return null;
1097
+ }
1098
+ return agg["returnData"];
1099
+ });
1100
+ return data;
1101
+ } catch (err) {
1102
+ console.error(err);
1103
+ return Array(calls.length).fill(null);
1104
+ }
1105
+ }
1106
+ async getBalances(address, xTokens) {
1107
+ if (!address) return {};
1108
+ const balances = {};
1109
+ const nativeXToken = xTokens.find((xToken) => isNativeToken(xToken));
1110
+ const nonNativeXTokens = xTokens.filter((xToken) => !isNativeToken(xToken));
1111
+ if (nativeXToken) {
1112
+ const balance = await this.iconService.getBalance(address).execute();
1113
+ balances[nativeXToken.address] = BigInt(balance.toFixed());
1114
+ }
1115
+ const cds = nonNativeXTokens.map((token) => {
1116
+ return {
1117
+ target: token.address,
1118
+ method: "balanceOf",
1119
+ params: [address]
1120
+ };
1121
+ });
1122
+ const data = await this.getAggregateData(
1123
+ false,
1124
+ cds.filter((cd) => cd.target.startsWith("cx"))
1125
+ );
1126
+ return nonNativeXTokens.reduce((agg, token, idx) => {
1127
+ const balance = data[idx];
1128
+ balances[token.address] = BigInt(balance);
1129
+ return agg;
1130
+ }, balances);
1131
+ }
1132
+ };
1133
+
1134
+ // src/xchains/icon/iconex/index.tsx
1135
+ var ICONEX_RELAY_RESPONSE = "ICONEX_RELAY_RESPONSE";
1136
+ var ICONEX_RELAY_REQUEST = "ICONEX_RELAY_REQUEST";
1137
+ var request = (event) => {
1138
+ return new Promise((resolve, reject) => {
1139
+ const handler = (evt) => {
1140
+ window.removeEventListener(ICONEX_RELAY_RESPONSE, handler);
1141
+ resolve(evt.detail);
1142
+ };
1143
+ window.addEventListener(ICONEX_RELAY_RESPONSE, handler);
1144
+ window.dispatchEvent(
1145
+ new CustomEvent(ICONEX_RELAY_REQUEST, {
1146
+ detail: event
1147
+ })
1148
+ );
1149
+ });
1150
+ };
1151
+
1152
+ // src/xchains/icon/IconHanaXConnector.ts
1153
+ var IconHanaXConnector = class extends XConnector {
1154
+ constructor() {
1155
+ super("ICON", "Hana Wallet", "hana");
1156
+ }
1157
+ async connect() {
1158
+ const { hanaWallet } = window;
1159
+ if (window && !hanaWallet && !hanaWallet?.isAvailable) {
1160
+ window.open("https://chromewebstore.google.com/detail/hana-wallet/jfdlamikmbghhapbgfoogdffldioobgl", "_blank");
1161
+ return;
1162
+ }
1163
+ const detail = await request({
1164
+ type: "REQUEST_ADDRESS" /* REQUEST_ADDRESS */
1165
+ });
1166
+ if (detail?.type === "RESPONSE_ADDRESS" /* RESPONSE_ADDRESS */) {
1167
+ return {
1168
+ address: detail?.payload,
1169
+ xChainType: this.xChainType
1170
+ };
1171
+ }
1172
+ return void 0;
1173
+ }
1174
+ async disconnect() {
1175
+ console.log("HanaIconXConnector disconnected");
1176
+ }
1177
+ get icon() {
1178
+ return "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/hana.svg";
1179
+ }
1180
+ };
1181
+
1182
+ // src/useXWagmiStore.ts
872
1183
  var initXServices = () => {
873
1184
  const xServices = {};
874
- ["EVM", "INJECTIVE", "STELLAR", "SUI", "SOLANA", "ICON", "NEAR"].forEach((key) => {
1185
+ ["EVM", "BITCOIN", "INJECTIVE", "STELLAR", "SUI", "SOLANA", "ICON", "NEAR"].forEach((key) => {
875
1186
  const xChainType = key;
876
1187
  switch (xChainType) {
877
1188
  // EVM, SUI, Solana wallet connectors are supported by their own sdks. wagmi, @mysten/dapp-kit, @solana/wallet-adapter-react.
@@ -887,6 +1198,14 @@ var initXServices = () => {
887
1198
  xServices[xChainType] = SolanaXService.getInstance();
888
1199
  xServices[xChainType].setXConnectors([]);
889
1200
  break;
1201
+ case "BITCOIN":
1202
+ xServices[xChainType] = BitcoinXService.getInstance();
1203
+ xServices[xChainType].setXConnectors([
1204
+ new UnisatXConnector(),
1205
+ new XverseXConnector(),
1206
+ new OKXXConnector()
1207
+ ]);
1208
+ break;
890
1209
  // Injective, Stellar, Icon wallet connectors are supported by sodax wallet-sdk-react sdk.
891
1210
  case "INJECTIVE":
892
1211
  xServices[xChainType] = InjectiveXService.getInstance();
@@ -1099,6 +1418,25 @@ function useXConnect() {
1099
1418
  }
1100
1419
  });
1101
1420
  }
1421
+
1422
+ // src/xchains/solana/SolanaXConnector.ts
1423
+ var SolanaXConnector = class extends XConnector {
1424
+ constructor(wallet) {
1425
+ super("SOLANA", wallet?.adapter.name, wallet?.adapter.name);
1426
+ this.wallet = wallet;
1427
+ }
1428
+ getXService() {
1429
+ return SolanaXService.getInstance();
1430
+ }
1431
+ async connect() {
1432
+ return;
1433
+ }
1434
+ async disconnect() {
1435
+ }
1436
+ get icon() {
1437
+ return this.wallet?.adapter.icon;
1438
+ }
1439
+ };
1102
1440
  var useStellarXConnectors = () => {
1103
1441
  const xService = useXService("STELLAR");
1104
1442
  return reactQuery.useQuery({
@@ -1245,8 +1583,7 @@ function useXBalances({
1245
1583
  const balances = await xService.getBalances(address, xTokens);
1246
1584
  return balances;
1247
1585
  },
1248
- enabled: !!xService,
1249
- placeholderData: reactQuery.keepPreviousData,
1586
+ enabled: !!xService && !!address && (xTokens?.length ?? 0) > 0,
1250
1587
  refetchInterval: 5e3
1251
1588
  });
1252
1589
  }
@@ -1313,6 +1650,7 @@ function useWalletProvider(spokeChainId) {
1313
1650
  const { data: evmWalletClient } = wagmi.useWalletClient();
1314
1651
  const xService = useXService(getXChainType(spokeChainId));
1315
1652
  const xAccount = useXAccount(spokeChainId);
1653
+ const xConnection = useXConnection(xChainType);
1316
1654
  return React2.useMemo(() => {
1317
1655
  switch (xChainType) {
1318
1656
  case "EVM": {
@@ -1376,9 +1714,15 @@ function useWalletProvider(spokeChainId) {
1376
1714
  }
1377
1715
  return new walletSdkCore.SolanaWalletProvider({
1378
1716
  wallet: solanaXService.wallet,
1379
- connection: solanaXService.connection
1717
+ endpoint: solanaXService.connection.rpcEndpoint
1380
1718
  });
1381
1719
  }
1720
+ case "BITCOIN": {
1721
+ if (!xConnection?.xConnectorId) return void 0;
1722
+ const connector = BitcoinXService.getInstance().getXConnectorById(xConnection.xConnectorId);
1723
+ if (!connector) return void 0;
1724
+ return connector.recreateWalletProvider(xConnection.xAccount);
1725
+ }
1382
1726
  case "NEAR": {
1383
1727
  const nearXService = xService;
1384
1728
  if (!nearXService.walletSelector) {
@@ -1389,7 +1733,7 @@ function useWalletProvider(spokeChainId) {
1389
1733
  default:
1390
1734
  return void 0;
1391
1735
  }
1392
- }, [xChainType, evmPublicClient, evmWalletClient, xService, xAccount]);
1736
+ }, [xChainType, evmPublicClient, evmWalletClient, xService, xAccount, xConnection]);
1393
1737
  }
1394
1738
  function useXSignMessage() {
1395
1739
  const { signMessage } = walletAdapterReact.useWallet();
@@ -1445,10 +1789,13 @@ function useXSignMessage() {
1445
1789
  }
1446
1790
  });
1447
1791
  }
1448
- function useAnchorProvider() {
1449
- const { connection } = walletAdapterReact.useConnection();
1450
- const wallet = walletAdapterReact.useWallet();
1451
- return new anchor.AnchorProvider(connection, wallet, { commitment: "confirmed" });
1792
+
1793
+ // src/xchains/bitcoin/useBitcoinXConnectors.ts
1794
+ function useBitcoinXConnectors() {
1795
+ const xService = useXService("BITCOIN");
1796
+ return React2.useMemo(() => {
1797
+ return xService?.getXConnectors() || [];
1798
+ }, [xService]);
1452
1799
  }
1453
1800
  var Hydrate = () => {
1454
1801
  const suiClient = dappKit.useSuiClient();
@@ -1471,7 +1818,6 @@ var Hydrate = () => {
1471
1818
  }, [suiAccount]);
1472
1819
  const { connection: solanaConnection } = walletAdapterReact.useConnection();
1473
1820
  const solanaWallet = walletAdapterReact.useWallet();
1474
- const solanaProvider = useAnchorProvider();
1475
1821
  React2.useEffect(() => {
1476
1822
  if (solanaConnection) {
1477
1823
  SolanaXService.getInstance().connection = solanaConnection;
@@ -1482,11 +1828,6 @@ var Hydrate = () => {
1482
1828
  SolanaXService.getInstance().wallet = solanaWallet;
1483
1829
  }
1484
1830
  }, [solanaWallet]);
1485
- React2.useEffect(() => {
1486
- if (solanaProvider) {
1487
- SolanaXService.getInstance().provider = solanaProvider;
1488
- }
1489
- }, [solanaProvider]);
1490
1831
  const wagmiConfig = wagmi.useConfig();
1491
1832
  React2.useEffect(() => {
1492
1833
  if (wagmiConfig) {
@@ -1547,7 +1888,7 @@ var SodaxWalletProvider = ({ children, rpcConfig }) => {
1547
1888
  return createWagmiConfig(rpcConfig);
1548
1889
  }, [rpcConfig]);
1549
1890
  const wallets = React2.useMemo(() => [new walletAdapterWallets.UnsafeBurnerWalletAdapter()], []);
1550
- return /* @__PURE__ */ React2__default.default.createElement(reactQuery.QueryClientProvider, { client: queryClient }, /* @__PURE__ */ React2__default.default.createElement(wagmi.WagmiProvider, { reconnectOnMount: false, config: wagmiConfig }, /* @__PURE__ */ React2__default.default.createElement(dappKit.SuiClientProvider, { networks: { mainnet: { url: client.getFullnodeUrl("mainnet") } }, defaultNetwork: "mainnet" }, /* @__PURE__ */ React2__default.default.createElement(dappKit.WalletProvider, { autoConnect: true }, /* @__PURE__ */ React2__default.default.createElement(walletAdapterReact.ConnectionProvider, { endpoint: rpcConfig["solana"] ?? "" }, /* @__PURE__ */ React2__default.default.createElement(walletAdapterReact.WalletProvider, { wallets, autoConnect: true }, /* @__PURE__ */ React2__default.default.createElement(Hydrate, null), children))))));
1891
+ return /* @__PURE__ */ React2__default.default.createElement(reactQuery.QueryClientProvider, { client: queryClient }, /* @__PURE__ */ React2__default.default.createElement(wagmi.WagmiProvider, { reconnectOnMount: false, config: wagmiConfig }, /* @__PURE__ */ React2__default.default.createElement(dappKit.SuiClientProvider, { networks: { mainnet: { url: client.getFullnodeUrl("mainnet") } }, defaultNetwork: "mainnet" }, /* @__PURE__ */ React2__default.default.createElement(dappKit.WalletProvider, { autoConnect: true }, /* @__PURE__ */ React2__default.default.createElement(walletAdapterReact.ConnectionProvider, { endpoint: rpcConfig["solana"] ?? "https://api.mainnet-beta.solana.com" }, /* @__PURE__ */ React2__default.default.createElement(walletAdapterReact.WalletProvider, { wallets, autoConnect: true }, /* @__PURE__ */ React2__default.default.createElement(Hydrate, null), children))))));
1551
1892
  };
1552
1893
  reconnectIcon();
1553
1894
  reconnectStellar();
@@ -1562,6 +1903,8 @@ var WalletId = /* @__PURE__ */ ((WalletId2) => {
1562
1903
  return WalletId2;
1563
1904
  })(WalletId || {});
1564
1905
 
1906
+ exports.BitcoinXConnector = BitcoinXConnector;
1907
+ exports.BitcoinXService = BitcoinXService;
1565
1908
  exports.EvmXConnector = EvmXConnector;
1566
1909
  exports.EvmXService = EvmXService;
1567
1910
  exports.IconHanaXConnector = IconHanaXConnector;
@@ -1569,6 +1912,7 @@ exports.IconXService = IconXService;
1569
1912
  exports.InjectiveKelprXConnector = InjectiveKelprXConnector;
1570
1913
  exports.InjectiveMetamaskXConnector = InjectiveMetamaskXConnector;
1571
1914
  exports.InjectiveXService = InjectiveXService;
1915
+ exports.OKXXConnector = OKXXConnector;
1572
1916
  exports.SodaxWalletProvider = SodaxWalletProvider;
1573
1917
  exports.SolanaXConnector = SolanaXConnector;
1574
1918
  exports.SolanaXService = SolanaXService;
@@ -1576,14 +1920,17 @@ exports.StellarWalletsKitXConnector = StellarWalletsKitXConnector;
1576
1920
  exports.StellarXService = StellarXService;
1577
1921
  exports.SuiXConnector = SuiXConnector;
1578
1922
  exports.SuiXService = SuiXService;
1923
+ exports.UnisatXConnector = UnisatXConnector;
1579
1924
  exports.WalletId = WalletId;
1580
1925
  exports.XConnector = XConnector;
1581
1926
  exports.XService = XService;
1927
+ exports.XverseXConnector = XverseXConnector;
1582
1928
  exports.getWagmiChainId = getWagmiChainId;
1583
1929
  exports.getXChainType = getXChainType;
1584
1930
  exports.getXService = getXService;
1585
1931
  exports.isNativeToken = isNativeToken;
1586
1932
  exports.switchEthereumChain = switchEthereumChain;
1933
+ exports.useBitcoinXConnectors = useBitcoinXConnectors;
1587
1934
  exports.useEvmSwitchChain = useEvmSwitchChain;
1588
1935
  exports.useWalletProvider = useWalletProvider;
1589
1936
  exports.useXAccount = useXAccount;