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

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 (127) hide show
  1. package/README.md +107 -142
  2. package/dist/XConnector-12q0OVe5.d.ts +146 -0
  3. package/dist/chunk-7V7O3Q7Y.mjs +62 -0
  4. package/dist/chunk-C6M34IVL.mjs +86 -0
  5. package/dist/chunk-DQTYAMKF.mjs +1609 -0
  6. package/dist/chunk-FSOGMSJH.mjs +39 -0
  7. package/dist/chunk-IFXZQW4C.mjs +98 -0
  8. package/dist/chunk-JQ4H4GJ5.mjs +100 -0
  9. package/dist/chunk-LKSSME2J.mjs +31 -0
  10. package/dist/chunk-MWWVB7TD.mjs +123 -0
  11. package/dist/chunk-NAKCAL2M.mjs +32 -0
  12. package/dist/chunk-OPYSVPRW.mjs +144 -0
  13. package/dist/chunk-QMXBY3UI.mjs +1 -0
  14. package/dist/chunk-TACW7Z4D.mjs +31 -0
  15. package/dist/chunk-WPZOLGVB.mjs +148 -0
  16. package/dist/chunk-X7BHR7WS.mjs +200 -0
  17. package/dist/chunk-Z5GXDHGL.mjs +190 -0
  18. package/dist/config-DEsqgrG1.d.ts +151 -0
  19. package/dist/index.d.ts +768 -1498
  20. package/dist/index.mjs +453 -2005
  21. package/dist/xchains/bitcoin/index.d.ts +125 -0
  22. package/dist/xchains/bitcoin/index.mjs +14 -0
  23. package/dist/xchains/evm/index.d.ts +39 -0
  24. package/dist/xchains/evm/index.mjs +3 -0
  25. package/dist/xchains/icon/index.d.ts +37 -0
  26. package/dist/xchains/icon/index.mjs +5 -0
  27. package/dist/xchains/injective/index.d.ts +35 -0
  28. package/dist/xchains/injective/index.mjs +3 -0
  29. package/dist/xchains/near/index.d.ts +34 -0
  30. package/dist/xchains/near/index.mjs +4 -0
  31. package/dist/xchains/solana/index.d.ts +26 -0
  32. package/dist/xchains/solana/index.mjs +5 -0
  33. package/dist/xchains/stacks/index.d.ts +42 -0
  34. package/dist/xchains/stacks/index.mjs +3 -0
  35. package/dist/xchains/stellar/index.d.ts +44 -0
  36. package/dist/xchains/stellar/index.mjs +4 -0
  37. package/dist/xchains/sui/index.d.ts +37 -0
  38. package/dist/xchains/sui/index.mjs +5 -0
  39. package/docs/ADDING_A_NEW_CHAIN.md +440 -0
  40. package/docs/ARCHITECTURE.md +291 -0
  41. package/docs/BATCH_OPERATIONS.md +267 -0
  42. package/docs/CHAIN_DETECTION.md +216 -0
  43. package/docs/CONFIGURE_PROVIDER.md +360 -0
  44. package/docs/CONNECTORS.md +247 -0
  45. package/docs/CONNECT_FLOW.md +276 -0
  46. package/docs/EVM_SWITCH_CHAIN.md +161 -0
  47. package/docs/SIGN_MESSAGE.md +213 -0
  48. package/docs/SUB_PATH_EXPORTS.md +218 -0
  49. package/docs/WALLETCONNECT.md +154 -0
  50. package/docs/WALLET_MODAL.md +331 -0
  51. package/docs/WALLET_PROVIDER_BRIDGE.md +226 -0
  52. package/package.json +56 -22
  53. package/dist/index.cjs +0 -2147
  54. package/dist/index.cjs.map +0 -1
  55. package/dist/index.d.cts +0 -1579
  56. package/dist/index.mjs.map +0 -1
  57. package/src/Hydrate.ts +0 -65
  58. package/src/SodaxWalletProvider.tsx +0 -97
  59. package/src/actions/getXChainType.ts +0 -8
  60. package/src/actions/getXService.ts +0 -33
  61. package/src/actions/index.ts +0 -2
  62. package/src/assets/wallets/hana.svg +0 -6
  63. package/src/assets/wallets/havah.svg +0 -76
  64. package/src/assets/wallets/keplr.svg +0 -30
  65. package/src/assets/wallets/metamask.svg +0 -60
  66. package/src/assets/wallets/phantom.svg +0 -4
  67. package/src/assets/wallets/sui.svg +0 -20
  68. package/src/core/XConnector.ts +0 -54
  69. package/src/core/XService.ts +0 -85
  70. package/src/core/index.ts +0 -2
  71. package/src/hooks/index.ts +0 -11
  72. package/src/hooks/useEthereumChainId.ts +0 -44
  73. package/src/hooks/useEvmSwitchChain.ts +0 -91
  74. package/src/hooks/useWalletProvider.ts +0 -206
  75. package/src/hooks/useXAccount.ts +0 -51
  76. package/src/hooks/useXAccounts.ts +0 -56
  77. package/src/hooks/useXBalances.ts +0 -65
  78. package/src/hooks/useXConnect.ts +0 -118
  79. package/src/hooks/useXConnection.ts +0 -72
  80. package/src/hooks/useXConnectors.ts +0 -72
  81. package/src/hooks/useXDisconnect.ts +0 -73
  82. package/src/hooks/useXService.ts +0 -8
  83. package/src/hooks/useXSignMessage.ts +0 -82
  84. package/src/index.ts +0 -19
  85. package/src/types/index.ts +0 -22
  86. package/src/useXWagmiStore.ts +0 -116
  87. package/src/utils/index.ts +0 -21
  88. package/src/xchains/bitcoin/BitcoinXConnector.ts +0 -34
  89. package/src/xchains/bitcoin/BitcoinXService.ts +0 -40
  90. package/src/xchains/bitcoin/OKXXConnector.ts +0 -117
  91. package/src/xchains/bitcoin/UnisatXConnector.ts +0 -117
  92. package/src/xchains/bitcoin/XverseXConnector.ts +0 -232
  93. package/src/xchains/bitcoin/index.ts +0 -7
  94. package/src/xchains/bitcoin/useBitcoinXConnectors.ts +0 -14
  95. package/src/xchains/evm/EvmXConnector.ts +0 -27
  96. package/src/xchains/evm/EvmXService.ts +0 -211
  97. package/src/xchains/evm/index.ts +0 -3
  98. package/src/xchains/icon/IconHanaXConnector.ts +0 -39
  99. package/src/xchains/icon/IconXService.ts +0 -117
  100. package/src/xchains/icon/actions.ts +0 -28
  101. package/src/xchains/icon/iconex/index.tsx +0 -46
  102. package/src/xchains/icon/index.ts +0 -2
  103. package/src/xchains/injective/InjectiveXConnector.ts +0 -60
  104. package/src/xchains/injective/InjectiveXService.ts +0 -62
  105. package/src/xchains/injective/actions.ts +0 -32
  106. package/src/xchains/injective/index.ts +0 -2
  107. package/src/xchains/near/NearXConnector.ts +0 -42
  108. package/src/xchains/near/NearXService.ts +0 -46
  109. package/src/xchains/near/useNearXConnectors.ts +0 -23
  110. package/src/xchains/solana/SolanaXConnector.ts +0 -26
  111. package/src/xchains/solana/SolanaXService.ts +0 -46
  112. package/src/xchains/solana/index.ts +0 -2
  113. package/src/xchains/stacks/StacksXConnector.ts +0 -63
  114. package/src/xchains/stacks/StacksXService.ts +0 -59
  115. package/src/xchains/stacks/constants.ts +0 -42
  116. package/src/xchains/stacks/index.ts +0 -4
  117. package/src/xchains/stacks/useStacksXConnectors.ts +0 -7
  118. package/src/xchains/stellar/CustomSorobanServer.ts +0 -93
  119. package/src/xchains/stellar/StellarWalletsKitXConnector.ts +0 -53
  120. package/src/xchains/stellar/StellarXService.ts +0 -93
  121. package/src/xchains/stellar/actions.ts +0 -24
  122. package/src/xchains/stellar/index.tsx +0 -2
  123. package/src/xchains/stellar/useStellarXConnectors.ts +0 -21
  124. package/src/xchains/stellar/utils.ts +0 -49
  125. package/src/xchains/sui/SuiXConnector.ts +0 -28
  126. package/src/xchains/sui/SuiXService.ts +0 -66
  127. package/src/xchains/sui/index.ts +0 -2
@@ -0,0 +1,39 @@
1
+ import { isNativeToken } from './chunk-7V7O3Q7Y.mjs';
2
+ import { XService } from './chunk-IFXZQW4C.mjs';
3
+ import { PublicKey } from '@solana/web3.js';
4
+ import { getAssociatedTokenAddressSync, getAccount } from '@solana/spl-token';
5
+
6
+ var SolanaXService = class _SolanaXService extends XService {
7
+ static instance;
8
+ connection;
9
+ wallet;
10
+ constructor() {
11
+ super("SOLANA");
12
+ }
13
+ static getInstance() {
14
+ if (!_SolanaXService.instance) {
15
+ _SolanaXService.instance = new _SolanaXService();
16
+ }
17
+ return _SolanaXService.instance;
18
+ }
19
+ async getBalance(address, xToken) {
20
+ if (!address) return BigInt(0);
21
+ const connection = this.connection;
22
+ if (!connection) {
23
+ return BigInt(0);
24
+ }
25
+ try {
26
+ if (isNativeToken(xToken)) {
27
+ const newBalance = await connection.getBalance(new PublicKey(address));
28
+ return BigInt(newBalance);
29
+ }
30
+ const tokenAccountPubkey = getAssociatedTokenAddressSync(new PublicKey(xToken.address), new PublicKey(address));
31
+ const tokenAccount = await getAccount(connection, tokenAccountPubkey);
32
+ return BigInt(tokenAccount.amount);
33
+ } catch {
34
+ return BigInt(0);
35
+ }
36
+ }
37
+ };
38
+
39
+ export { SolanaXService };
@@ -0,0 +1,98 @@
1
+ // src/core/XService.ts
2
+ var XService = class {
3
+ /** The blockchain type this service handles */
4
+ xChainType;
5
+ /** Available wallet connectors for this chain */
6
+ xConnectors = [];
7
+ constructor(xChainType) {
8
+ this.xChainType = xChainType;
9
+ }
10
+ /**
11
+ * Gets the balance of a specific token for an address
12
+ * @param address The wallet address to check
13
+ * @param xToken The token to get the balance for
14
+ * @returns Promise resolving to the token balance as a bigint
15
+ */
16
+ async getBalance(address, xToken) {
17
+ return 0n;
18
+ }
19
+ /**
20
+ * Gets balances for multiple tokens for an address
21
+ * @param address The wallet address to check
22
+ * @param xTokens Array of tokens to get balances for
23
+ * @returns Promise resolving to object mapping token addresses to balances
24
+ */
25
+ async getBalances(address, xTokens) {
26
+ if (!address) return {};
27
+ const balancePromises = xTokens.map(async (xToken) => {
28
+ const balance = await this.getBalance(address, xToken);
29
+ return { address: xToken.address, balance };
30
+ });
31
+ const balances = await Promise.all(balancePromises);
32
+ return balances.reduce((acc, { address: address2, balance }) => {
33
+ acc[address2] = balance;
34
+ return acc;
35
+ }, {});
36
+ }
37
+ /**
38
+ * Gets all available connectors for this chain
39
+ */
40
+ getXConnectors() {
41
+ return this.xConnectors;
42
+ }
43
+ /**
44
+ * Sets the available connectors for this chain
45
+ */
46
+ setXConnectors(xConnectors) {
47
+ this.xConnectors = xConnectors;
48
+ }
49
+ /**
50
+ * Gets a specific connector by its ID
51
+ * @param xConnectorId The connector ID to look up
52
+ * @returns The matching connector or undefined if not found
53
+ */
54
+ getXConnectorById(xConnectorId) {
55
+ return this.getXConnectors().find((xConnector) => xConnector.id === xConnectorId);
56
+ }
57
+ };
58
+
59
+ // src/core/XConnector.ts
60
+ var XConnector = class {
61
+ /** The blockchain type this connector supports */
62
+ xChainType;
63
+ /** Display name of the wallet provider */
64
+ name;
65
+ /** Unique identifier for the connector */
66
+ _id;
67
+ /** Optional icon URL for the wallet provider */
68
+ _icon;
69
+ constructor(xChainType, name, id) {
70
+ this.xChainType = xChainType;
71
+ this.name = name;
72
+ this._id = id;
73
+ }
74
+ /** Get the unique identifier for this connector */
75
+ get id() {
76
+ return this._id;
77
+ }
78
+ /** Get the optional icon URL for this wallet provider */
79
+ get icon() {
80
+ return this._icon;
81
+ }
82
+ /**
83
+ * True when the wallet extension backing this connector is installed.
84
+ * Default: true (for provider-managed chains where connector presence already
85
+ * implies install — EVM via EIP-6963, Solana/Sui via adapter discovery).
86
+ * Subclasses backed by extension injection (Bitcoin, ICON, Stacks) override
87
+ * this with a window probe.
88
+ */
89
+ get isInstalled() {
90
+ return true;
91
+ }
92
+ /** URL to install the wallet extension when missing. Subclasses override. */
93
+ get installUrl() {
94
+ return void 0;
95
+ }
96
+ };
97
+
98
+ export { XConnector, XService };
@@ -0,0 +1,100 @@
1
+ import { assertSuiProviderShape, assert, isRecord, hasStringProperty, hasOptionalStringProperty } from './chunk-TACW7Z4D.mjs';
2
+ import { isNativeToken } from './chunk-7V7O3Q7Y.mjs';
3
+ import { XService, XConnector } from './chunk-IFXZQW4C.mjs';
4
+ import { SuiWalletProvider } from '@sodax/wallet-sdk-core';
5
+
6
+ var SuiXService = class _SuiXService extends XService {
7
+ static instance;
8
+ // Hydrated by SuiHydrator. Start undefined because wallet may not be connected yet.
9
+ // suiClient is typed structurally for the methods we call directly.
10
+ // suiWallet/suiAccount are opaque — stored and passed through to SuiWalletProvider.
11
+ suiClient;
12
+ suiWallet;
13
+ suiAccount;
14
+ constructor() {
15
+ super("SUI");
16
+ }
17
+ static getInstance() {
18
+ if (!_SuiXService.instance) {
19
+ _SuiXService.instance = new _SuiXService();
20
+ }
21
+ return _SuiXService.instance;
22
+ }
23
+ createWalletProvider() {
24
+ if (!this.suiClient || !this.suiWallet || !this.suiAccount) {
25
+ console.warn(
26
+ "[SuiXService] createWalletProvider: missing dependencies \u2014 wallet not connected yet",
27
+ { hasClient: !!this.suiClient, hasWallet: !!this.suiWallet, hasAccount: !!this.suiAccount }
28
+ );
29
+ return void 0;
30
+ }
31
+ assertSuiProviderShape("SuiXService", this.suiClient, this.suiWallet, this.suiAccount);
32
+ return new SuiWalletProvider({
33
+ client: this.suiClient,
34
+ wallet: this.suiWallet,
35
+ account: this.suiAccount
36
+ });
37
+ }
38
+ // getBalance is not used because getBalances uses getAllBalances which returns all balances
39
+ async getBalances(address, xTokens) {
40
+ if (!address || !this.suiClient) return {};
41
+ const client = this.suiClient;
42
+ try {
43
+ const balancePromises = xTokens.map(async (xToken) => {
44
+ let coinType = isNativeToken(xToken) ? "0x2::sui::SUI" : xToken.address;
45
+ if (coinType === "0x03917a812fe4a6d6bc779c5ab53f8a80ba741f8af04121193fc44e0f662e2ceb::balanced_dollar::BALANCED_DOLLAR") {
46
+ coinType = "0x3917a812fe4a6d6bc779c5ab53f8a80ba741f8af04121193fc44e0f662e2ceb::balanced_dollar::BALANCED_DOLLAR";
47
+ }
48
+ const balance = await client.getBalance({
49
+ owner: address,
50
+ coinType
51
+ });
52
+ return {
53
+ address: xToken.address,
54
+ balance: balance ? BigInt(balance.totalBalance) : void 0
55
+ };
56
+ });
57
+ const results = await Promise.all(balancePromises);
58
+ const tokenMap = {};
59
+ results.forEach((result) => {
60
+ if (result.balance !== void 0) {
61
+ tokenMap[result.address] = result.balance;
62
+ }
63
+ });
64
+ return tokenMap;
65
+ } catch (error) {
66
+ console.error("[wallet-sdk-react] SUI getBalances failed:", error);
67
+ return {};
68
+ }
69
+ }
70
+ };
71
+
72
+ // src/xchains/sui/SuiXConnector.ts
73
+ var isSuiWalletInfo = (value) => {
74
+ return isRecord(value) && hasStringProperty(value, "name") && // Some wallets may not expose `id` — in that case we fall back to `name` for stability.
75
+ // We still validate if it exists.
76
+ hasOptionalStringProperty(value, "id") && hasOptionalStringProperty(value, "icon");
77
+ };
78
+ var SuiXConnector = class extends XConnector {
79
+ wallet;
80
+ constructor(wallet) {
81
+ assert(isSuiWalletInfo(wallet), "[SuiXConnector] invalid wallet object");
82
+ const id = wallet.id ?? wallet.name;
83
+ assert(typeof id === "string" && id.length > 0, "[SuiXConnector] invalid wallet id");
84
+ super("SUI", wallet.name, id);
85
+ this.wallet = { id, name: wallet.name, icon: wallet.icon };
86
+ }
87
+ getXService() {
88
+ return SuiXService.getInstance();
89
+ }
90
+ async connect() {
91
+ return;
92
+ }
93
+ async disconnect() {
94
+ }
95
+ get icon() {
96
+ return this.wallet.icon;
97
+ }
98
+ };
99
+
100
+ export { SuiXConnector, SuiXService };
@@ -0,0 +1,31 @@
1
+ import { SolanaXService } from './chunk-FSOGMSJH.mjs';
2
+ import { XConnector } from './chunk-IFXZQW4C.mjs';
3
+
4
+ // src/xchains/solana/SolanaXConnector.ts
5
+ var SolanaXConnector = class extends XConnector {
6
+ wallet;
7
+ constructor(wallet) {
8
+ super("SOLANA", wallet?.adapter.name, wallet?.adapter.name);
9
+ this.wallet = wallet;
10
+ }
11
+ getXService() {
12
+ return SolanaXService.getInstance();
13
+ }
14
+ async connect() {
15
+ return;
16
+ }
17
+ async disconnect() {
18
+ }
19
+ get icon() {
20
+ return this.wallet?.adapter.icon;
21
+ }
22
+ get isInstalled() {
23
+ const state = this.wallet?.readyState;
24
+ return state === "Installed" || state === "Loadable";
25
+ }
26
+ get installUrl() {
27
+ return this.wallet?.adapter.url;
28
+ }
29
+ };
30
+
31
+ export { SolanaXConnector };
@@ -0,0 +1,123 @@
1
+ import { XService, XConnector } from './chunk-IFXZQW4C.mjs';
2
+ import { getNetworkEndpoints, Network } from '@injectivelabs/networks';
3
+ import { IndexerGrpcAccountPortfolioApi, ChainGrpcWasmApi, getInjectiveAddress } from '@injectivelabs/sdk-ts';
4
+ import { ChainId } from '@injectivelabs/ts-types';
5
+ import { MsgBroadcaster } from '@injectivelabs/wallet-core';
6
+ import { mainnet } from 'wagmi/chains';
7
+ import { WalletStrategy } from '@sodax/libs/injective/wallet-strategy';
8
+ import { isCosmosBrowserWallet, isEvmBrowserWallet } from '@injectivelabs/wallet-base';
9
+ import { isCosmosWalletInstalled } from '@injectivelabs/wallet-cosmos';
10
+
11
+ var InjectiveXService = class _InjectiveXService extends XService {
12
+ static instance;
13
+ walletStrategy;
14
+ indexerGrpcAccountPortfolioApi;
15
+ chainGrpcWasmApi;
16
+ msgBroadcaster;
17
+ constructor(rpcConfig) {
18
+ super("INJECTIVE");
19
+ const defaults = getNetworkEndpoints(Network.Mainnet);
20
+ const endpoints = {
21
+ ...defaults,
22
+ indexer: rpcConfig?.indexer || defaults.indexer,
23
+ grpc: rpcConfig?.grpc || defaults.grpc
24
+ };
25
+ this.walletStrategy = new WalletStrategy({
26
+ chainId: ChainId.Mainnet,
27
+ strategies: {},
28
+ evmOptions: {
29
+ evmChainId: mainnet.id,
30
+ rpcUrl: mainnet.rpcUrls.default.http[0]
31
+ }
32
+ });
33
+ this.indexerGrpcAccountPortfolioApi = new IndexerGrpcAccountPortfolioApi(endpoints.indexer);
34
+ this.chainGrpcWasmApi = new ChainGrpcWasmApi(endpoints.grpc);
35
+ this.msgBroadcaster = new MsgBroadcaster({
36
+ walletStrategy: this.walletStrategy,
37
+ network: Network.Mainnet,
38
+ endpoints
39
+ });
40
+ }
41
+ /**
42
+ * @param rpcConfig - Only applied on first call. Subsequent calls return the
43
+ * existing instance unchanged — gRPC/Indexer clients are built in the
44
+ * constructor and can't be rebuilt at runtime. Pass the desired endpoints
45
+ * via `SodaxWalletProvider.config.rpcConfig` once at app init.
46
+ */
47
+ static getInstance(rpcConfig) {
48
+ if (!_InjectiveXService.instance) {
49
+ _InjectiveXService.instance = new _InjectiveXService(rpcConfig);
50
+ }
51
+ return _InjectiveXService.instance;
52
+ }
53
+ async getBalance(address, xToken) {
54
+ if (!address) return 0n;
55
+ const portfolio = await this.indexerGrpcAccountPortfolioApi.fetchAccountPortfolioBalances(address);
56
+ const xTokenAddress = xToken.address;
57
+ const balance = portfolio.bankBalancesList.find((_balance) => _balance.denom === xTokenAddress);
58
+ if (balance) {
59
+ return BigInt(balance.amount);
60
+ }
61
+ return 0n;
62
+ }
63
+ };
64
+ var WALLET_ICONS = {
65
+ metamask: "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/metamask.svg",
66
+ keplr: "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/keplr.svg",
67
+ leap: "https://assets.leapwallet.io/logos/leap-cosmos-logo.svg",
68
+ rabby: "https://raw.githubusercontent.com/RabbyHub/logo/master/symbol.svg",
69
+ phantom: "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/phantom.svg",
70
+ "okx-wallet": "https://static.okx.com/cdn/assets/imgs/247/58E63FEA47A2B7D7.png",
71
+ "trust-wallet": "https://trustwallet.com/assets/images/media/assets/twLogo.svg"
72
+ };
73
+ var InjectiveXConnector = class extends XConnector {
74
+ wallet;
75
+ constructor(name, wallet) {
76
+ super("INJECTIVE", name, wallet);
77
+ this.wallet = wallet;
78
+ }
79
+ getXService() {
80
+ return InjectiveXService.getInstance();
81
+ }
82
+ async connect() {
83
+ if (isCosmosBrowserWallet(this.wallet) && !isCosmosWalletInstalled(this.wallet)) {
84
+ console.warn(`[InjectiveXConnector] connect: ${this.wallet} cosmos wallet not installed`);
85
+ return void 0;
86
+ }
87
+ const walletStrategy = this.getXService().walletStrategy;
88
+ await walletStrategy.setWallet(this.wallet);
89
+ const addresses = await walletStrategy.getAddresses();
90
+ if (!addresses?.length) {
91
+ console.warn(`[InjectiveXConnector] connect: ${this.wallet} returned no addresses`);
92
+ return void 0;
93
+ }
94
+ const firstAddress = addresses[0];
95
+ if (!firstAddress) {
96
+ console.warn(`[InjectiveXConnector] connect: ${this.wallet} returned empty addresses array`);
97
+ return void 0;
98
+ }
99
+ const address = isEvmBrowserWallet(this.wallet) ? getInjectiveAddress(firstAddress) : firstAddress;
100
+ return {
101
+ address,
102
+ xChainType: this.xChainType
103
+ };
104
+ }
105
+ async disconnect() {
106
+ if (isEvmBrowserWallet(this.wallet)) {
107
+ const walletStrategy = this.getXService().walletStrategy;
108
+ await walletStrategy.setWallet(this.wallet);
109
+ await walletStrategy.disconnect();
110
+ }
111
+ }
112
+ get icon() {
113
+ return WALLET_ICONS[this.wallet];
114
+ }
115
+ get isInstalled() {
116
+ if (isCosmosBrowserWallet(this.wallet)) {
117
+ return isCosmosWalletInstalled(this.wallet);
118
+ }
119
+ return true;
120
+ }
121
+ };
122
+
123
+ export { InjectiveXConnector, InjectiveXService };
@@ -0,0 +1,32 @@
1
+ // src/constants.ts
2
+ var SUI_DEFAULT_NETWORK = "mainnet";
3
+ var SUI_DEFAULT_AUTO_CONNECT = true;
4
+ var EVM_DEFAULT_RECONNECT_ON_MOUNT = false;
5
+ var EVM_DEFAULT_SSR = true;
6
+ var SOLANA_DEFAULT_AUTO_CONNECT = true;
7
+ var SOLANA_DEFAULT_RPC_URL = "https://api.mainnet-beta.solana.com";
8
+ var SOLANA_METAMASK_CONNECT_TIMEOUT_MS = 3e4;
9
+ var BITCOIN_DEFAULT_RPC_URL = "https://mempool.space/api";
10
+ var STELLAR_DEFAULT_HORIZON_RPC_URL = "https://horizon.stellar.org";
11
+ var STELLAR_DEFAULT_SOROBAN_RPC_URL = "https://rpc.ankr.com/stellar_soroban";
12
+ var NEAR_DEFAULT_RPC_URL = "https://1rpc.io/near";
13
+ var WALLET_METADATA = {
14
+ unisat: {
15
+ installUrl: "https://chromewebstore.google.com/detail/unisat-wallet/ppbibelpcjmhbdihakflkdcoccbgbkpo",
16
+ icon: "https://avatars.githubusercontent.com/u/125119198?s=200&v=4"
17
+ },
18
+ xverse: {
19
+ installUrl: "https://chromewebstore.google.com/detail/xverse-bitcoin-crypto-wal/idnnbdplmphpflfnlkomgpfbpcgelopg",
20
+ icon: "https://cdn.brandfetch.io/iddzGN5Rcv/w/400/h/400/theme/dark/icon.jpeg?c=1bxid64Mup7aczewSAYMX&t=1771902357797"
21
+ },
22
+ okx: {
23
+ installUrl: "https://chromewebstore.google.com/detail/okx-wallet/mcohilncbfahbmgdjkbpemcciiolgcge",
24
+ icon: "https://static.okx.com/cdn/assets/imgs/247/58E63FEA47A2B7D7.png"
25
+ },
26
+ hana: {
27
+ installUrl: "https://chromewebstore.google.com/detail/hana-wallet/jfdlamikmbghhapbgfoogdffldioobgl",
28
+ icon: "https://raw.githubusercontent.com/balancednetwork/icons/master/wallets/hana.svg"
29
+ }
30
+ };
31
+
32
+ export { BITCOIN_DEFAULT_RPC_URL, EVM_DEFAULT_RECONNECT_ON_MOUNT, EVM_DEFAULT_SSR, NEAR_DEFAULT_RPC_URL, SOLANA_DEFAULT_AUTO_CONNECT, SOLANA_DEFAULT_RPC_URL, SOLANA_METAMASK_CONNECT_TIMEOUT_MS, STELLAR_DEFAULT_HORIZON_RPC_URL, STELLAR_DEFAULT_SOROBAN_RPC_URL, SUI_DEFAULT_AUTO_CONNECT, SUI_DEFAULT_NETWORK, WALLET_METADATA };
@@ -0,0 +1,144 @@
1
+ import { XService, XConnector } from './chunk-IFXZQW4C.mjs';
2
+ import { networkFrom, fetchCallReadOnlyFunction, Cl } from '@sodax/libs/stacks/core';
3
+ import { request, disconnect } from '@sodax/libs/stacks/connect';
4
+ import { useMemo } from 'react';
5
+
6
+ var StacksXService = class _StacksXService extends XService {
7
+ static instance;
8
+ network;
9
+ constructor(network) {
10
+ super("STACKS");
11
+ this.network = networkFrom(network || "mainnet");
12
+ }
13
+ static getInstance(network) {
14
+ if (!_StacksXService.instance) {
15
+ _StacksXService.instance = new _StacksXService(network);
16
+ } else if (network) {
17
+ _StacksXService.instance.network = networkFrom(network);
18
+ }
19
+ return _StacksXService.instance;
20
+ }
21
+ /**
22
+ * @warning Network / fetch / contract-read failures are silently swallowed —
23
+ * `0n` is returned on any error. Callers cannot distinguish "zero balance"
24
+ * from "fetch failed"; UI that needs to surface the failure must wrap this
25
+ * call externally and re-fetch on its own error path.
26
+ */
27
+ async getBalance(address, xToken) {
28
+ if (!address) return 0n;
29
+ if (xToken.symbol === "STX") {
30
+ const url = `${this.network.client.baseUrl}/extended/v1/address/${address}/balances`;
31
+ try {
32
+ const response = await fetch(url);
33
+ if (!response.ok) {
34
+ throw new Error(`Error fetching data: ${response.statusText}`);
35
+ }
36
+ const data = await response.json();
37
+ return BigInt(data.stx.balance);
38
+ } catch (error) {
39
+ console.error("Error fetching STX balance:", error);
40
+ return 0n;
41
+ }
42
+ }
43
+ const parts = xToken.address.split(".");
44
+ const contractAddress = parts[0] ?? "";
45
+ const contractName = parts[1] ?? "";
46
+ try {
47
+ const result = await fetchCallReadOnlyFunction({
48
+ contractAddress,
49
+ contractName,
50
+ functionName: "get-balance",
51
+ functionArgs: [Cl.principal(address)],
52
+ network: this.network,
53
+ senderAddress: address
54
+ });
55
+ return result.value.value;
56
+ } catch (error) {
57
+ console.error("Error fetching token balance:", error);
58
+ return 0n;
59
+ }
60
+ }
61
+ };
62
+ function getProviderFromId(id) {
63
+ if (typeof window === "undefined") return void 0;
64
+ return id.split(".").reduce((acc, part) => acc?.[part], window);
65
+ }
66
+ var StacksXConnector = class extends XConnector {
67
+ config;
68
+ constructor(config) {
69
+ super("STACKS", config.name, config.id);
70
+ this.config = config;
71
+ }
72
+ async connect() {
73
+ const provider = this.getProvider();
74
+ if (!provider) {
75
+ throw new Error(`${this.config.name} is not installed. Install the extension and reload the page.`);
76
+ }
77
+ const response = await request({ provider }, "stx_getAddresses");
78
+ const stxAddress = response.addresses.find((a) => a.purpose === "stacks");
79
+ if (!stxAddress) {
80
+ console.warn(
81
+ `[StacksXConnector] ${this.config.name}: no address with purpose="stacks" returned from stx_getAddresses`,
82
+ response.addresses
83
+ );
84
+ return void 0;
85
+ }
86
+ return {
87
+ address: stxAddress.address,
88
+ xChainType: this.xChainType
89
+ };
90
+ }
91
+ async disconnect() {
92
+ disconnect();
93
+ }
94
+ get icon() {
95
+ return this.config.icon;
96
+ }
97
+ get isInstalled() {
98
+ if (typeof window === "undefined") return false;
99
+ return getProviderFromId(this.config.id) !== void 0;
100
+ }
101
+ get installUrl() {
102
+ return this.config.installUrl;
103
+ }
104
+ getProvider() {
105
+ return getProviderFromId(this.config.id);
106
+ }
107
+ };
108
+
109
+ // src/xchains/stacks/constants.ts
110
+ var LEATHER_ICON = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCIgdmlld0JveD0iMCAwIDEyOCAxMjgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxMjgiIGhlaWdodD0iMTI4IiByeD0iMjYuODM4NyIgZmlsbD0iIzEyMTAwRiIvPgo8cGF0aCBkPSJNNzQuOTE3MSA1Mi43MTE0QzgyLjQ3NjYgNTEuNTQwOCA5My40MDg3IDQzLjU4MDQgOTMuNDA4NyAzNy4zNzYxQzkzLjQwODcgMzUuNTAzMSA5MS44OTY4IDM0LjIxNTQgODkuNjg3MSAzNC4yMTU0Qzg1LjUwMDQgMzQuMjE1NCA3OC40MDYxIDQwLjUzNjggNzQuOTE3MSA1Mi43MTE0Wk0zOS45MTEgODMuNDk5MUMzMC4wMjU2IDgzLjQ5OTEgMjkuMjExNSA5My4zMzI0IDM5LjA5NjkgOTMuMzMyNEM0My41MTYzIDkzLjMzMjQgNDguODY2MSA5MS41NzY0IDUxLjY1NzMgODguNDE1N0M0Ny41ODY4IDg0LjkwMzggNDQuMjE0MSA4My40OTkxIDM5LjkxMSA4My40OTkxWk0xMDIuODI5IDc5LjI4NDhDMTAzLjQxIDk1Ljc5MDcgOTUuMDM2OSAxMDUuMDM5IDgwLjg0ODQgMTA1LjAzOUM3Mi40NzQ4IDEwNS4wMzkgNjguMjg4MSAxMDEuODc4IDU5LjMzMyA5Ni4wMjQ5QzU0LjY4MSAxMDEuMTc2IDQ1Ljg0MjMgMTA1LjAzOSAzOC41MTU0IDEwNS4wMzlDMTMuMjc4NSAxMDUuMDM5IDE0LjMyNTIgNzIuODQ2MyA0MC4wMjczIDcyLjg0NjNDNDUuMzc3MSA3Mi44NDYzIDQ5LjkxMjggNzQuMjUxMSA1NS43Mjc3IDc3Ljg4TDU5LjU2NTYgNjQuNDE3N0M0My43NDg5IDYwLjA4NjQgMzUuODQwNSA0Ny45MTE4IDQzLjYzMjYgMzAuNDY5M0g1Ni4xOTI5QzQ5LjIxNSA0Mi4wNTg2IDUzLjk4MzIgNTEuNjU3OCA2Mi44MjIgNTIuNzExNEM2Ny41OTAzIDM1LjczNzIgNzcuODI0NiAyMi41MDkgOTEuNDMxNiAyMi41MDlDOTkuMTA3NCAyMi41MDkgMTA1LjE1NSAyNy41NDI4IDEwNS4xNTUgMzYuNjczN0MxMDUuMTU1IDUxLjMwNjYgODYuMDgxOSA2My4yNDcxIDcxLjY2MDcgNjQuNDE3N0w2NS43Mjk1IDg1LjM3MjFDNzIuNDc0OCA5My4yMTUzIDkxLjE5OSAxMDAuODI0IDkxLjE5OSA3OS4yODQ4SDEwMi44MjlaIiBmaWxsPSIjRjVGMUVEIi8+Cjwvc3ZnPgo=";
111
+ var XVERSE_ICON = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MDAiIGhlaWdodD0iNjAwIj48ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGZpbGw9IiMxNzE3MTciIGQ9Ik0wIDBoNjAwdjYwMEgweiIvPjxwYXRoIGZpbGw9IiNGRkYiIGZpbGwtcnVsZT0ibm9uemVybyIgZD0iTTQ0MCA0MzUuNHYtNTFjMC0yLS44LTMuOS0yLjItNS4zTDIyMCAxNjIuMmE3LjYgNy42IDAgMCAwLTUuNC0yLjJoLTUxLjFjLTIuNSAwLTQuNiAyLTQuNiA0LjZ2NDcuM2MwIDIgLjggNCAyLjIgNS40bDc4LjIgNzcuOGE0LjYgNC42IDAgMCAxIDAgNi41bC03OSA3OC43Yy0xIC45LTEuNCAyLTEuNCAzLjJ2NTJjMCAyLjQgMiA0LjUgNC42IDQuNUgyNDljMi42IDAgNC42LTIgNC42LTQuNlY0MDVjMC0xLjIuNS0yLjQgMS40LTMuM2w0Mi40LTQyLjJhNC42IDQuNiAwIDAgMSA2LjQgMGw3OC43IDc4LjRhNy42IDcuNiAwIDAgMCA1LjQgMi4yaDQ3LjVjMi41IDAgNC42LTIgNC42LTQuNloiLz48cGF0aCBmaWxsPSIjRUU3QTMwIiBmaWxsLXJ1bGU9Im5vbnplcm8iIGQ9Ik0zMjUuNiAyMjcuMmg0Mi44YzIuNiAwIDQuNiAyLjEgNC42IDQuNnY0Mi42YzAgNCA1IDYuMSA4IDMuMmw1OC43LTU4LjVjLjgtLjggMS4zLTIgMS4zLTMuMnYtNTEuMmMwLTIuNi0yLTQuNi00LjYtNC42TDM4NCAxNjBjLTEuMiAwLTIuNC41LTMuMyAxLjNsLTU4LjQgNTguMWE0LjYgNC42IDAgMCAwIDMuMiA3LjhaIi8+PC9nPjwvc3ZnPg==";
112
+ var ASIGNA_ICON = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMDEwMCIgZD0iTTAgMGgzMnYzMkgweiIvPjxwYXRoIGZpbGw9InVybCgjYSkiIGQ9Ik0xNS4xMSA1LjU1YTMgMyAwIDAgMC0xLjgyIDEuM2wtLjA1LjA4LS40My43Mi0uMDcuMTEtLjUuODUtLjA1LjA5LTEuMjkgMi4xOC0uMDQuMDctLjQ3LjgtLjA2LjEtLjQ2Ljc4LS4wNy4xMS0xLjYzIDIuNzYtLjA3LjExLS4zOC42Ni0uMDUuMDgtLjczIDEuMjQtLjM1LjYtLjQuNjctLjA1LjA5TDUuMSAyMC43bC0uMTEuMTgtLjE0LjIzLS4wNy4xMy0uMzMuNTUtLjA0LjA3di4wMWExLjI2IDEuMjYgMCAwIDAtLjE0LjQ3IDEuMzEgMS4zMSAwIDAgMCAxLjI0IDEuNGgxLjVsLjA1LS4wNi4wNC0uMDYuODctMS4yMS4wNS0uMDguNzctMS4wNy4wNS0uMDcuNC0uNTcuMDUtLjA2LjI0LS4zNGExLjUyIDEuNTIgMCAwIDEgMS4zOS0uNjIgMS41IDEuNSAwIDAgMSAuNjQuMiAxLjQ3IDEuNDcgMCAwIDEgLjczIDEuMjcgMS40NCAxLjQ0IDAgMCAxLS4yNy44NGwtLjYzLjg4LS4wNS4wNy0uMzIuNDUtLjA2LjA4LS4wOC4xMi0uMTIuMTYtLjA1LjA4aDIuMTNhMi4zMiAyLjMyIDAgMCAwIDEuNzctLjk2bDEuMTgtMS42My43Ny0xLjA4IDEuMy0xLjhhMS4yNCAxLjI0IDAgMCAxIC41NS0uNDNsLjA4LS4wM2ExLjMgMS4zIDAgMCAxIC4zLS4wNiAxLjI4IDEuMjggMCAwIDEgMS4xNS41NGwuMTEuMmExLjEzIDEuMTMgMCAwIDEgLjEuNDEgMS4xOSAxLjE5IDAgMCAxLS4yMy43N2wtLjAzLjA1LS41Ny44LS43Ljk4LS4yNy4zN2ExLjIyIDEuMjIgMCAwIDAtLjIuNSAxLjA1IDEuMDUgMCAwIDAtLjAyLjIzdi4wNmExLjE3IDEuMTcgMCAwIDAgLjE0LjQzbC4wMi4wNS4wNy4xYTEuNDQgMS40NCAwIDAgMCAuMS4xMWwuMDUuMDYuMDEuMDFhMS44IDEuOCAwIDAgMCAuMTQuMWMwIC4wMi4wMi4wMy4wNC4wM2ExIDEgMCAwIDAgLjA4LjA1bC4wNy4wNGExLjI1IDEuMjUgMCAwIDAgLjUuMWg2LjljLjEgMCAuMi0uMDEuMjktLjAzbC4wNi0uMDJhMS4yNyAxLjI3IDAgMCAwIC4yNy0uMS41Ny41NyAwIDAgMCAuMDctLjAzIDEuMjEgMS4yMSAwIDAgMCAuMjYtLjE5bC4wOC0uMDdhLjkyLjkyIDAgMCAwIC4xNS0uMTkgMS41NSAxLjU1IDAgMCAwIC4wOS0uMTdsLjAyLS4wNWExLjIyIDEuMjIgMCAwIDAgLjA4LS4yNnYtLjA0bC4wMi0uMDh2LS4wOGExLjMyIDEuMzIgMCAwIDAtLjItLjc0bC0xLjYtMi42NC0uMDYtLjEtLjItLjMyLS4zMy0uNTR2LS4wMWwtLjA1LS4wOC0xLjMtMi4xNS0uMDctLjEtLjA0LS4wNi0uOC0xLjMyLS4wNC0uMDctLjItLjM0LS4xLS4xNC0uMS0uMTYtLjUzLS45LS4xMy0uMi0uMDktLjE0LTIuMTctMy41Ny0uMDQtLjA3LS43Mi0xLjE5LS4wNS0uMDctLjQtLjY1YTIuNjUgMi42NSAwIDAgMC0uMy0uNCAyLjk2IDIuOTYgMCAwIDAtLjk3LS43NCAzLjA0IDMuMDQgMCAwIDAtMS4zLS4zYy0uMjUgMC0uNS4wNC0uNzQuMVoiLz48cGF0aCBmaWxsPSJ1cmwoI2IpIiBkPSJNMTkgMTYuM2E1LjQ1IDUuNDUgMCAwIDAtLjgzIDEuNTZsLS4wNC4xNWExLjM2IDEuMzYgMCAwIDEgLjI4LS4xNiAxLjI0IDEuMjQgMCAwIDEgLjM4LS4wOGguMWExLjI4IDEuMjggMCAwIDEgMS4wNS41NGMuMDQuMDYuMDguMTMuMS4yYTEuMjQgMS4yNCAwIDAgMSAuMDkuMjcgMS4xOSAxLjE5IDAgMCAxLS4yLjkxbC0uMDQuMDUtLjU3Ljc5LS43Ljk5LS4yNy4zN2ExLjIzIDEuMjMgMCAwIDAtLjIuNDIgMS4wNiAxLjA2IDAgMCAwLS4wMi4zMXYuMDZhMS4xNyAxLjE3IDAgMCAwIC4xNi40Ny45My45MyAwIDAgMCAuMDcuMSAxLjUgMS41IDAgMCAwIC4xLjEybC4wNS4wNmguMDFhMS45NCAxLjk0IDAgMCAwIC4wOS4wOCAxIDEgMCAwIDAgLjE3LjFsLjA3LjA0YTEuMjUgMS4yNSAwIDAgMCAuNS4xaDYuOWMuMSAwIC4yIDAgLjI4LS4wMmwuMDctLjAyYTEuMzIgMS4zMiAwIDAgMCAuMzQtLjEzbC4xNi0uMS4wMy0uMDNhMS4yOSAxLjI5IDAgMCAwIC4yLS4yIDIuNDMgMi40MyAwIDAgMCAuMTItLjE3Yy4wMy0uMDMuMDUtLjA4LjA3LS4xMmwuMDItLjA1YTEuMjEgMS4yMSAwIDAgMCAuMDktLjN2LS4wOGwuMDEtLjA5YTEuMzIgMS4zMiAwIDAgMC0uMi0uNzNsLTEuNi0yLjY0LS4wNi0uMS0uMi0uMzItLjMzLS41NHYtLjAybC0uMDUtLjA3LTEuMy0yLjE1LS4xMi0uMDctLjA3LS4wNGE0Ljk0IDQuOTQgMCAwIDAtMi40Ni0uNjdjLTEuMDMgMC0xLjc2LjU3LTIuMjYgMS4yWiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMi4yOSAyMS4wOGMwIC4yOS0uMDkuNTgtLjI3Ljg0bC0xLjMxIDEuODRIN2wyLjUyLTMuNTNhMS41NCAxLjU0IDAgMCAxIDIuMS0uMzZjLjQzLjI4LjY2Ljc0LjY2IDEuMloiLz48cGF0aCBmaWxsPSIjMDAwIiBkPSJNMTEuMTYgMjEuMjVhLjU2LjU2IDAgMCAxLS41Ny41NS41Ni41NiAwIDAgMS0uNTctLjU2LjU2LjU2IDAgMCAxIC41Ny0uNTUuNTYuNTYgMCAwIDEgLjU3LjU2WiIvPjxkZWZzPjxsaW5lYXJHcmFkaWVudCBpZD0iYSIgeDE9IjE1LjIzIiB4Mj0iMTkuMyIgeTE9IjI1Ljc4IiB5Mj0iNi4xMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPjxzdG9wIHN0b3AtY29sb3I9IiM2NTIyRjQiLz48c3RvcCBvZmZzZXQ9Ii41NSIgc3RvcC1jb2xvcj0iIzlCNkJGRiIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0E1ODVGRiIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJiIiB4MT0iMjIuNTkiIHgyPSIyNC44IiB5MT0iMjQuNzEiIHkyPSIxNS41MyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPjxzdG9wIHN0b3AtY29sb3I9IiM0MjFGOEIiLz48c3RvcCBvZmZzZXQ9Ii41NSIgc3RvcC1jb2xvcj0iIzcyMzBGRiIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzk3NzNGRiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjwvc3ZnPg==";
113
+ var FORDEFI_ICON = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDIiIGhlaWdodD0iNDIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZmlsbD0iIzEwMTExNCIgZD0iTTAgMGg0MnY0MkgweiIvPgogIDxwYXRoIGQ9Ik0xOS40NyAyNi44OUg1djMuNTdhNC41NyA0LjU3IDAgMCAwIDQuNTggNC41N2g1LjgzbDQuMDYtOC4xNFoiIGZpbGw9IiM3OTk0RkYiLz4KICA8cGF0aCBkPSJNNSAxNy40aDI3LjU4bC0zLjIgNi43OEg1VjE3LjRaIiBmaWxsPSIjNDg2REZGIi8+CiAgPHBhdGggZD0iTTE0LjY3IDdINXY3LjY4aDMzVjdoLTkuNjd2NS43NGgtMlY3aC05LjY3djUuNzRoLTEuOTlWN1oiIGZpbGw9IiM1Q0QxRkEiLz4KPC9zdmc+Cg==";
114
+ var STACKS_PROVIDERS = [
115
+ {
116
+ id: "LeatherProvider",
117
+ name: "Leather",
118
+ icon: LEATHER_ICON,
119
+ installUrl: "https://chrome.google.com/webstore/detail/hiro-wallet/ldinpeekobnhjjdofggfgjlcehhmanlj"
120
+ },
121
+ {
122
+ id: "XverseProviders.BitcoinProvider",
123
+ name: "Xverse Wallet",
124
+ icon: XVERSE_ICON,
125
+ installUrl: "https://chrome.google.com/webstore/detail/xverse-wallet/idnnbdplmphpflfnlkomgpfbpcgelopg"
126
+ },
127
+ {
128
+ id: "AsignaProvider",
129
+ name: "Asigna Multisig",
130
+ icon: ASIGNA_ICON,
131
+ installUrl: "https://stx.asigna.io/"
132
+ },
133
+ {
134
+ id: "FordefiProviders.UtxoProvider",
135
+ name: "Fordefi",
136
+ icon: FORDEFI_ICON,
137
+ installUrl: "https://chromewebstore.google.com/detail/fordefi/hcmehenccjdmfbojapcbcofkgdpbnlle"
138
+ }
139
+ ];
140
+ function useStacksXConnectors() {
141
+ return useMemo(() => STACKS_PROVIDERS.map((config) => new StacksXConnector(config)), []);
142
+ }
143
+
144
+ export { STACKS_PROVIDERS, StacksXConnector, StacksXService, useStacksXConnectors };
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,31 @@
1
+ // src/shared/guards.ts
2
+ function isRecord(value) {
3
+ return typeof value === "object" && value !== null;
4
+ }
5
+ function hasStringProperty(value, key) {
6
+ return isRecord(value) && typeof value[key] === "string";
7
+ }
8
+ function hasOptionalStringProperty(value, key) {
9
+ return isRecord(value) && (value[key] === void 0 || typeof value[key] === "string");
10
+ }
11
+ function hasBooleanProperty(value, key) {
12
+ return isRecord(value) && typeof value[key] === "boolean";
13
+ }
14
+ function hasFunctionProperty(value, key) {
15
+ return isRecord(value) && typeof value[key] === "function";
16
+ }
17
+ function assert(condition, message) {
18
+ if (!condition) {
19
+ throw new Error(message);
20
+ }
21
+ }
22
+ function assertSuiProviderShape(caller, client, wallet, account) {
23
+ const clientOk = isRecord(client) && hasFunctionProperty(client, "executeTransactionBlock") && hasFunctionProperty(client, "devInspectTransactionBlock") && hasFunctionProperty(client, "getCoins");
24
+ assert(clientOk, `[${caller}] invalid Sui client shape`);
25
+ const walletOk = isRecord(wallet) && hasStringProperty(wallet, "name");
26
+ assert(walletOk, `[${caller}] invalid Sui wallet shape`);
27
+ const accountOk = isRecord(account) && hasStringProperty(account, "address");
28
+ assert(accountOk, `[${caller}] invalid Sui account shape`);
29
+ }
30
+
31
+ export { assert, assertSuiProviderShape, hasBooleanProperty, hasFunctionProperty, hasOptionalStringProperty, hasStringProperty, isRecord };