@sodax/wallet-sdk-react 2.0.0-rc.2 → 2.0.0-rc.20

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 (141) hide show
  1. package/README.md +14 -7
  2. package/dist/{XConnector-B9YQTVJ4.d.ts → XConnector-12q0OVe5.d.ts} +1 -1
  3. package/dist/{chunk-NY7U7OJW.mjs → chunk-7V7O3Q7Y.mjs} +0 -2
  4. package/dist/{chunk-BXJLBR4G.mjs → chunk-C6M34IVL.mjs} +2 -4
  5. package/dist/{chunk-X2MHIWXO.mjs → chunk-IFXZQW4C.mjs} +0 -2
  6. package/dist/{chunk-7ULB6DW4.mjs → chunk-JQ4H4GJ5.mjs} +3 -5
  7. package/dist/{chunk-PLCA4ZDJ.mjs → chunk-JTQGKX65.mjs} +254 -52
  8. package/dist/{chunk-E5IAZ7E6.mjs → chunk-LM7R5APS.mjs} +22 -11
  9. package/dist/{chunk-BKJB527E.mjs → chunk-MWWVB7TD.mjs} +2 -4
  10. package/dist/{chunk-MXZVF5HR.mjs → chunk-NAKCAL2M.mjs} +0 -2
  11. package/dist/{chunk-PJLEJVAU.mjs → chunk-OPX55MQO.mjs} +11 -6
  12. package/dist/chunk-QMXBY3UI.mjs +1 -0
  13. package/dist/{chunk-MAQ47Q52.mjs → chunk-TACW7Z4D.mjs} +0 -2
  14. package/dist/chunk-VPNYFVP6.mjs +53 -0
  15. package/dist/{chunk-2BOUGCJ7.mjs → chunk-WX23SYR6.mjs} +4 -6
  16. package/dist/{chunk-66BAUK56.mjs → chunk-X7BHR7WS.mjs} +4 -6
  17. package/dist/{chunk-N5A2TMF6.mjs → chunk-XJA2MJMG.mjs} +2 -4
  18. package/dist/{config-OlnzyEUE.d.ts → config-DEsqgrG1.d.ts} +10 -5
  19. package/dist/index.d.ts +6 -6
  20. package/dist/index.mjs +20 -31
  21. package/dist/xchains/bitcoin/index.d.ts +20 -3
  22. package/dist/xchains/bitcoin/index.mjs +14 -16
  23. package/dist/xchains/evm/index.d.ts +3 -3
  24. package/dist/xchains/evm/index.mjs +3 -5
  25. package/dist/xchains/icon/index.d.ts +1 -1
  26. package/dist/xchains/icon/index.mjs +5 -7
  27. package/dist/xchains/injective/index.d.ts +2 -2
  28. package/dist/xchains/injective/index.mjs +3 -5
  29. package/dist/xchains/near/index.d.ts +1 -1
  30. package/dist/xchains/near/index.mjs +4 -6
  31. package/dist/xchains/solana/index.d.ts +1 -1
  32. package/dist/xchains/solana/index.mjs +5 -7
  33. package/dist/xchains/stacks/index.d.ts +10 -4
  34. package/dist/xchains/stacks/index.mjs +3 -5
  35. package/dist/xchains/stellar/index.d.ts +1 -1
  36. package/dist/xchains/stellar/index.mjs +4 -6
  37. package/dist/xchains/sui/index.d.ts +1 -1
  38. package/dist/xchains/sui/index.mjs +5 -7
  39. package/package.json +37 -29
  40. package/ai-exported/AGENTS.md +0 -122
  41. package/ai-exported/integration/README.md +0 -102
  42. package/ai-exported/integration/ai-rules.md +0 -136
  43. package/ai-exported/integration/architecture.md +0 -181
  44. package/ai-exported/integration/examples/01-minimal-evm.tsx +0 -75
  45. package/ai-exported/integration/examples/02-multi-chain-modal.tsx +0 -169
  46. package/ai-exported/integration/examples/03-nextjs-app-router.tsx +0 -99
  47. package/ai-exported/integration/examples/04-walletconnect-setup.tsx +0 -89
  48. package/ai-exported/integration/examples/README.md +0 -29
  49. package/ai-exported/integration/recipes/batch-operations.md +0 -223
  50. package/ai-exported/integration/recipes/bridge-to-sdk.md +0 -164
  51. package/ai-exported/integration/recipes/chain-detection.md +0 -254
  52. package/ai-exported/integration/recipes/connect-button.md +0 -156
  53. package/ai-exported/integration/recipes/multi-chain-modal.md +0 -199
  54. package/ai-exported/integration/recipes/setup.md +0 -158
  55. package/ai-exported/integration/recipes/sign-message.md +0 -137
  56. package/ai-exported/integration/recipes/sub-path-imports.md +0 -95
  57. package/ai-exported/integration/recipes/switch-chain.md +0 -141
  58. package/ai-exported/integration/recipes/walletconnect-setup.md +0 -139
  59. package/ai-exported/integration/reference/api-surface.md +0 -175
  60. package/ai-exported/integration/reference/chain-support.md +0 -78
  61. package/ai-exported/integration/reference/connectors.md +0 -74
  62. package/ai-exported/integration/reference/hooks.md +0 -204
  63. package/ai-exported/integration/reference/wallet-brands.md +0 -106
  64. package/ai-exported/migration/README.md +0 -49
  65. package/ai-exported/migration/ai-rules.md +0 -144
  66. package/ai-exported/migration/breaking-changes.md +0 -305
  67. package/ai-exported/migration/checklist.md +0 -159
  68. package/ai-exported/migration/recipes/connect-button.md +0 -166
  69. package/ai-exported/migration/recipes/multi-chain-modal.md +0 -244
  70. package/ai-exported/migration/recipes/ssr-setup.md +0 -162
  71. package/ai-exported/migration/recipes/walletconnect-migration.md +0 -168
  72. package/ai-exported/migration/reference/components.md +0 -73
  73. package/ai-exported/migration/reference/config.md +0 -307
  74. package/ai-exported/migration/reference/hooks.md +0 -278
  75. package/ai-exported/migration/reference/imports.md +0 -157
  76. package/dist/chunk-2BOUGCJ7.mjs.map +0 -1
  77. package/dist/chunk-66BAUK56.mjs.map +0 -1
  78. package/dist/chunk-7ULB6DW4.mjs.map +0 -1
  79. package/dist/chunk-BKJB527E.mjs.map +0 -1
  80. package/dist/chunk-BXJLBR4G.mjs.map +0 -1
  81. package/dist/chunk-E5IAZ7E6.mjs.map +0 -1
  82. package/dist/chunk-MAQ47Q52.mjs.map +0 -1
  83. package/dist/chunk-MXZVF5HR.mjs.map +0 -1
  84. package/dist/chunk-N5A2TMF6.mjs.map +0 -1
  85. package/dist/chunk-NY7U7OJW.mjs.map +0 -1
  86. package/dist/chunk-PJLEJVAU.mjs.map +0 -1
  87. package/dist/chunk-PLCA4ZDJ.mjs.map +0 -1
  88. package/dist/chunk-TZMKDXFA.mjs +0 -3
  89. package/dist/chunk-TZMKDXFA.mjs.map +0 -1
  90. package/dist/chunk-X2MHIWXO.mjs.map +0 -1
  91. package/dist/chunk-XZ7CHO2S.mjs +0 -41
  92. package/dist/chunk-XZ7CHO2S.mjs.map +0 -1
  93. package/dist/index.cjs +0 -3337
  94. package/dist/index.cjs.map +0 -1
  95. package/dist/index.mjs.map +0 -1
  96. package/dist/xchains/bitcoin/index.cjs +0 -1927
  97. package/dist/xchains/bitcoin/index.cjs.map +0 -1
  98. package/dist/xchains/bitcoin/index.mjs.map +0 -1
  99. package/dist/xchains/evm/index.cjs +0 -316
  100. package/dist/xchains/evm/index.cjs.map +0 -1
  101. package/dist/xchains/evm/index.mjs.map +0 -1
  102. package/dist/xchains/icon/index.cjs +0 -311
  103. package/dist/xchains/icon/index.cjs.map +0 -1
  104. package/dist/xchains/icon/index.mjs.map +0 -1
  105. package/dist/xchains/injective/index.cjs +0 -223
  106. package/dist/xchains/injective/index.cjs.map +0 -1
  107. package/dist/xchains/injective/index.mjs.map +0 -1
  108. package/dist/xchains/near/index.cjs +0 -190
  109. package/dist/xchains/near/index.cjs.map +0 -1
  110. package/dist/xchains/near/index.mjs.map +0 -1
  111. package/dist/xchains/solana/index.cjs +0 -186
  112. package/dist/xchains/solana/index.cjs.map +0 -1
  113. package/dist/xchains/solana/index.mjs.map +0 -1
  114. package/dist/xchains/stacks/index.cjs +0 -240
  115. package/dist/xchains/stacks/index.cjs.map +0 -1
  116. package/dist/xchains/stacks/index.mjs.map +0 -1
  117. package/dist/xchains/stellar/index.cjs +0 -322
  118. package/dist/xchains/stellar/index.cjs.map +0 -1
  119. package/dist/xchains/stellar/index.mjs.map +0 -1
  120. package/dist/xchains/sui/index.cjs +0 -248
  121. package/dist/xchains/sui/index.cjs.map +0 -1
  122. package/dist/xchains/sui/index.mjs.map +0 -1
  123. package/docs/ADDING_A_NEW_CHAIN.md +0 -440
  124. package/docs/ARCHITECTURE.md +0 -291
  125. package/docs/BATCH_OPERATIONS.md +0 -267
  126. package/docs/CHAIN_DETECTION.md +0 -216
  127. package/docs/CONFIGURE_PROVIDER.md +0 -360
  128. package/docs/CONNECTORS.md +0 -247
  129. package/docs/CONNECT_FLOW.md +0 -276
  130. package/docs/EVM_SWITCH_CHAIN.md +0 -161
  131. package/docs/SIGN_MESSAGE.md +0 -213
  132. package/docs/SUB_PATH_EXPORTS.md +0 -246
  133. package/docs/WALLETCONNECT.md +0 -154
  134. package/docs/WALLET_MODAL.md +0 -331
  135. package/docs/WALLET_PROVIDER_BRIDGE.md +0 -226
  136. package/skills/SKILLS.md +0 -84
  137. package/skills/bridge-to-sdk.md +0 -148
  138. package/skills/connect-button.md +0 -116
  139. package/skills/evm-only-walletconnect.md +0 -111
  140. package/skills/multi-chain-modal.md +0 -178
  141. package/skills/setup.md +0 -107
package/README.md CHANGED
@@ -4,8 +4,8 @@ React layer over [`@sodax/wallet-sdk-core`](https://github.com/icon-project/soda
4
4
 
5
5
  ## Features
6
6
 
7
- - **Unified wallet connectivity** for 9 chain families across 20 chains
8
- - EVM (Sonic hub, Ethereum, Arbitrum, Base, BSC, Optimism, Polygon, Avalanche, HyperEVM, Lightlink, Redbelly, Kaia) — EIP-6963 + WalletConnect
7
+ - **Unified wallet connectivity** for 9 chain families across 21 chains
8
+ - EVM (Sonic hub, Ethereum, Arbitrum, Base, BSC, Optimism, Polygon, Avalanche, HyperEVM, Lightlink, Redbelly, Kaia, Hedera) — EIP-6963 + WalletConnect
9
9
  - Solana, Sui, Stellar, ICON, Injective, Bitcoin, NEAR, Stacks
10
10
  - **Single-store state** — `useXAccount`, `useXConnection`, `useXAccounts` all read the same Zustand slice; persisted to `localStorage`
11
11
  - **Bridge to `@sodax/sdk`** — `useWalletProvider` returns a typed `IXxxWalletProvider` ready to plug into any SDK call
@@ -117,14 +117,21 @@ The full guide lives in [`docs/`](docs/). Start with the topic that matches what
117
117
 
118
118
  ## AI agent docs
119
119
 
120
- This package ships with AI-consumable integration & migration docs at `node_modules/@sodax/wallet-sdk-react/ai-exported/`. Point your AI coding agent at [`ai-exported/AGENTS.md`](ai-exported/AGENTS.md) to start it routes to integration recipes (new consumers), migration recipes (v1 v2), and reference tables.
120
+ AI-readable docs for `@sodax/wallet-sdk-react` (and the other `@sodax/*` packages) are shipped via [`@sodax/skills`](https://github.com/icon-project/sodax-sdks/tree/main/packages/skills) — a separate npm package bundling Claude-Code SKILL.md files and a long-form knowledge tree.
121
121
 
122
+ **Recommended: [`skills` CLI](https://github.com/vercel-labs/skills)** — from your project root:
123
+
124
+ ```bash
125
+ npx skills@latest add icon-project/sodax-sdks/packages/skills
122
126
  ```
123
- > Read node_modules/@sodax/wallet-sdk-react/ai-exported/AGENTS.md and integrate
124
- > SODAX wallet connectivity into my Next.js app.
127
+
128
+ **npm + `AGENTS.md` pointer** (fallback for web chats, or when you prefer a devDependency over the CLI):
129
+
130
+ ```bash
131
+ pnpm add -D @sodax/skills
125
132
  ```
126
133
 
127
- The CI guard `scripts/check-ai-exported.sh` validates that every hook reference and sub-path in those docs resolves to a real export.
134
+ Then point your agent at `node_modules/@sodax/skills/AGENTS.md`. See [docs/ai-integration-guide.md](https://github.com/icon-project/sodax-sdks/blob/main/docs/ai-integration-guide.md) for all install modes and per-tool wiring.
128
135
 
129
136
  ---
130
137
 
@@ -147,7 +154,7 @@ See [Connectors](docs/CONNECTORS.md) for the full list of deep-import sub-paths.
147
154
 
148
155
  ## Requirements
149
156
 
150
- - Node.js >= 18.0.0
157
+ - Node.js >= 20.12.0
151
158
  - React >= 19
152
159
  - TypeScript
153
160
 
@@ -143,4 +143,4 @@ declare abstract class XConnector implements IXConnector {
143
143
  get installUrl(): string | undefined;
144
144
  }
145
145
 
146
- export { type IXConnector as I, type XAccount as X, type XConnection as a, XService as b, XConnector as c, type IXService as d };
146
+ export { type IXConnector as I, type XAccount as X, type IXService as a, type XConnection as b, XConnector as c, XService as d };
@@ -60,5 +60,3 @@ var getWagmiChainId = (xChainId) => {
60
60
  };
61
61
 
62
62
  export { getEntryDefaults, getRpcUrl, getWagmiChainId, isNativeToken, resolveEvmDefaults, sortConnectors };
63
- //# sourceMappingURL=chunk-NY7U7OJW.mjs.map
64
- //# sourceMappingURL=chunk-NY7U7OJW.mjs.map
@@ -1,5 +1,5 @@
1
- import { NEAR_DEFAULT_RPC_URL } from './chunk-MXZVF5HR.mjs';
2
- import { XService, XConnector } from './chunk-X2MHIWXO.mjs';
1
+ import { NEAR_DEFAULT_RPC_URL } from './chunk-NAKCAL2M.mjs';
2
+ import { XService, XConnector } from './chunk-IFXZQW4C.mjs';
3
3
  import { NearConnector } from '@hot-labs/near-connect';
4
4
  import { JsonRpcProvider } from 'near-api-js';
5
5
 
@@ -84,5 +84,3 @@ var NearXConnector = class extends XConnector {
84
84
  };
85
85
 
86
86
  export { NearXConnector, NearXService };
87
- //# sourceMappingURL=chunk-BXJLBR4G.mjs.map
88
- //# sourceMappingURL=chunk-BXJLBR4G.mjs.map
@@ -96,5 +96,3 @@ var XConnector = class {
96
96
  };
97
97
 
98
98
  export { XConnector, XService };
99
- //# sourceMappingURL=chunk-X2MHIWXO.mjs.map
100
- //# sourceMappingURL=chunk-X2MHIWXO.mjs.map
@@ -1,6 +1,6 @@
1
- import { assertSuiProviderShape, assert, isRecord, hasStringProperty, hasOptionalStringProperty } from './chunk-MAQ47Q52.mjs';
2
- import { isNativeToken } from './chunk-NY7U7OJW.mjs';
3
- import { XService, XConnector } from './chunk-X2MHIWXO.mjs';
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
4
  import { SuiWalletProvider } from '@sodax/wallet-sdk-core';
5
5
 
6
6
  var SuiXService = class _SuiXService extends XService {
@@ -98,5 +98,3 @@ var SuiXConnector = class extends XConnector {
98
98
  };
99
99
 
100
100
  export { SuiXConnector, SuiXService };
101
- //# sourceMappingURL=chunk-7ULB6DW4.mjs.map
102
- //# sourceMappingURL=chunk-7ULB6DW4.mjs.map
@@ -1,16 +1,16 @@
1
- import { StellarWalletsKitXConnector, StellarXService } from './chunk-66BAUK56.mjs';
2
- import { SuiXService } from './chunk-7ULB6DW4.mjs';
3
- import { EvmXService } from './chunk-E5IAZ7E6.mjs';
4
- import { IconHanaXConnector, IconXService, CHAIN_INFO } from './chunk-2BOUGCJ7.mjs';
5
- import { assert, isRecord, hasFunctionProperty } from './chunk-MAQ47Q52.mjs';
6
- import { InjectiveXConnector, InjectiveXService } from './chunk-BKJB527E.mjs';
7
- import { NearXService, NearXConnector } from './chunk-BXJLBR4G.mjs';
8
- import { BITCOIN_DEFAULT_RPC_URL, WALLET_METADATA } from './chunk-MXZVF5HR.mjs';
9
- import { SolanaXService } from './chunk-XZ7CHO2S.mjs';
10
- import { isNativeToken, getEntryDefaults, getRpcUrl } from './chunk-NY7U7OJW.mjs';
11
- import { STACKS_PROVIDERS, StacksXService, StacksXConnector } from './chunk-PJLEJVAU.mjs';
12
- import { XConnector, XService } from './chunk-X2MHIWXO.mjs';
13
- import { ChainTypeArr, baseChainInfo, ChainKeys, detectBitcoinAddressType, CHAIN_KEYS } from '@sodax/types';
1
+ import { SuiXService } from './chunk-JQ4H4GJ5.mjs';
2
+ import { NearXConnector, NearXService } from './chunk-C6M34IVL.mjs';
3
+ import { EvmXService } from './chunk-LM7R5APS.mjs';
4
+ import { IconHanaXConnector, CHAIN_INFO, IconXService } from './chunk-WX23SYR6.mjs';
5
+ import { assert, isRecord, hasFunctionProperty } from './chunk-TACW7Z4D.mjs';
6
+ import { InjectiveXConnector, InjectiveXService } from './chunk-MWWVB7TD.mjs';
7
+ import { SolanaXService } from './chunk-VPNYFVP6.mjs';
8
+ import { isNativeToken, getEntryDefaults, getRpcUrl } from './chunk-7V7O3Q7Y.mjs';
9
+ import { StacksXConnector, STACKS_PROVIDERS, StacksXService } from './chunk-OPX55MQO.mjs';
10
+ import { StellarWalletsKitXConnector, StellarXService } from './chunk-X7BHR7WS.mjs';
11
+ import { BITCOIN_DEFAULT_RPC_URL, WALLET_METADATA } from './chunk-NAKCAL2M.mjs';
12
+ import { XConnector, XService } from './chunk-IFXZQW4C.mjs';
13
+ import { ChainTypeArr, baseChainInfo, ChainKeys, usesBip322MessageSigning, detectBitcoinAddressType, CHAIN_KEYS } from '@sodax/types';
14
14
  import { AddressPurpose, MessageSigningProtocols } from 'sats-connect';
15
15
  import { createContext, useMemo, useSyncExternalStore, useCallback, useState, useRef, useContext, useEffect } from 'react';
16
16
  import { create } from 'zustand';
@@ -262,7 +262,7 @@ var XverseWalletProvider = class {
262
262
  var XVERSE_ADDRESS_TYPE_KEY = "xverse-address-type";
263
263
  var XverseXConnector = class _XverseXConnector extends BitcoinXConnector {
264
264
  walletProvider;
265
- /** Address purpose used when connecting. Taproot (Ordinals) by default to match Radfi. */
265
+ /** Address purpose used when connecting. Taproot (Ordinals) by default to match Bound Exchange. */
266
266
  addressPurpose;
267
267
  constructor(defaults) {
268
268
  super("Xverse", "xverse", defaults);
@@ -416,6 +416,190 @@ var OKXXConnector = class _OKXXConnector extends BitcoinXConnector {
416
416
  return new OKXWalletProvider(xAccount.address, this.defaults);
417
417
  }
418
418
  };
419
+ var HANA_PROVIDER_ID = "hanaWallet.bitcoin";
420
+ var BitcoinHanaWalletProvider = class {
421
+ chainType = "BITCOIN";
422
+ address;
423
+ publicKey;
424
+ defaults;
425
+ constructor(address, publicKey, defaults) {
426
+ this.address = address;
427
+ this.publicKey = publicKey;
428
+ this.defaults = defaults;
429
+ }
430
+ async getWalletAddress() {
431
+ return this.address;
432
+ }
433
+ async getPublicKey() {
434
+ return this.publicKey;
435
+ }
436
+ async getAddressType(_address) {
437
+ return detectBitcoinAddressType(this.address);
438
+ }
439
+ /**
440
+ * Parse a base64-encoded PSBT to count the number of inputs.
441
+ * Reads the unsigned transaction from the PSBT global section.
442
+ */
443
+ countPsbtInputs(psbtBase64) {
444
+ const data = Buffer.from(psbtBase64, "base64");
445
+ let offset = 5;
446
+ const keyLen = data[offset++] ?? 0;
447
+ if (keyLen !== 1 || data[offset++] !== 0) {
448
+ return 1;
449
+ }
450
+ const firstByte = data[offset++] ?? 0;
451
+ if (firstByte === 253) offset += 2;
452
+ else if (firstByte === 254) offset += 4;
453
+ else if (firstByte === 255) offset += 8;
454
+ offset += 4;
455
+ const inputByte = data[offset] ?? 0;
456
+ if (inputByte < 253) return inputByte;
457
+ return 1;
458
+ }
459
+ async signTransaction(psbtBase64, finalize) {
460
+ const effectiveFinalize = finalize ?? this.defaults?.defaultFinalize ?? false;
461
+ const { request } = await import('sats-connect');
462
+ const inputCount = this.countPsbtInputs(psbtBase64);
463
+ const signingIndexes = Array.from({ length: inputCount }, (_, i) => i);
464
+ const response = await request(
465
+ "signPsbt",
466
+ {
467
+ psbt: psbtBase64,
468
+ broadcast: false,
469
+ signInputs: {
470
+ [this.address]: signingIndexes
471
+ }
472
+ },
473
+ HANA_PROVIDER_ID
474
+ );
475
+ if (response.status === "error") {
476
+ throw new Error(response.error?.message || "Hana PSBT signing failed");
477
+ }
478
+ const result = response.result;
479
+ if (effectiveFinalize) {
480
+ return Buffer.from(result.psbt, "base64").toString("hex");
481
+ }
482
+ return result.psbt;
483
+ }
484
+ async signEcdsaMessage(message) {
485
+ const { request } = await import('sats-connect');
486
+ const response = await request(
487
+ "signMessage",
488
+ {
489
+ address: this.address,
490
+ message,
491
+ protocol: MessageSigningProtocols.ECDSA
492
+ },
493
+ HANA_PROVIDER_ID
494
+ );
495
+ if (response.status === "error") {
496
+ throw new Error(response.error?.message || "Hana ECDSA signing failed");
497
+ }
498
+ return response.result.signature;
499
+ }
500
+ async signBip322Message(message) {
501
+ const { request } = await import('sats-connect');
502
+ const response = await request(
503
+ "signMessage",
504
+ {
505
+ address: this.address,
506
+ message,
507
+ protocol: MessageSigningProtocols.BIP322
508
+ },
509
+ HANA_PROVIDER_ID
510
+ );
511
+ if (response.status === "error") {
512
+ throw new Error(response.error?.message || "Hana BIP322 signing failed");
513
+ }
514
+ return response.result.signature;
515
+ }
516
+ async sendBitcoin(toAddress, satoshis) {
517
+ const { request } = await import('sats-connect');
518
+ const response = await request(
519
+ "sendTransfer",
520
+ {
521
+ recipients: [
522
+ {
523
+ address: toAddress,
524
+ amount: Number(satoshis)
525
+ }
526
+ ]
527
+ },
528
+ HANA_PROVIDER_ID
529
+ );
530
+ if (response.status === "error") {
531
+ throw new Error(response.error?.message || "Hana sendTransfer failed");
532
+ }
533
+ return response.result.txid;
534
+ }
535
+ };
536
+ var HANA_ADDRESS_TYPE_KEY = "hana-address-type";
537
+ var BitcoinHanaXConnector = class _BitcoinHanaXConnector extends BitcoinXConnector {
538
+ walletProvider;
539
+ /** Address purpose used when connecting. Taproot (Ordinals) by default to match Bound Exchange. */
540
+ addressPurpose;
541
+ constructor(defaults) {
542
+ super("Hana Wallet", "hana-bitcoin", defaults);
543
+ const saved = typeof window !== "undefined" ? localStorage.getItem(HANA_ADDRESS_TYPE_KEY) : null;
544
+ this.addressPurpose = saved === "segwit" ? AddressPurpose.Payment : AddressPurpose.Ordinals;
545
+ }
546
+ /** Set address purpose and persist to localStorage. */
547
+ setAddressPurpose(type) {
548
+ this.addressPurpose = type === "taproot" ? AddressPurpose.Ordinals : AddressPurpose.Payment;
549
+ if (typeof window !== "undefined") {
550
+ localStorage.setItem(HANA_ADDRESS_TYPE_KEY, type);
551
+ }
552
+ }
553
+ static isAvailable() {
554
+ if (typeof window === "undefined") return false;
555
+ return !!window.hanaWallet?.bitcoin;
556
+ }
557
+ get isInstalled() {
558
+ return _BitcoinHanaXConnector.isAvailable();
559
+ }
560
+ get installUrl() {
561
+ return WALLET_METADATA.hana.installUrl;
562
+ }
563
+ get icon() {
564
+ return WALLET_METADATA.hana.icon;
565
+ }
566
+ async connect() {
567
+ if (!_BitcoinHanaXConnector.isAvailable()) {
568
+ throw new Error("Hana wallet is not installed");
569
+ }
570
+ const { request } = await import('sats-connect');
571
+ const response = await request(
572
+ "getAccounts",
573
+ {
574
+ purposes: [this.addressPurpose],
575
+ message: "Connect to Sodax"
576
+ },
577
+ HANA_PROVIDER_ID
578
+ );
579
+ if (response.status === "error") {
580
+ throw new Error(response.error?.message || "Hana connection failed");
581
+ }
582
+ const accounts = response.result;
583
+ const paymentAccount = accounts.find((a) => a.purpose === this.addressPurpose) || accounts[0];
584
+ if (!paymentAccount) return void 0;
585
+ this.walletProvider = new BitcoinHanaWalletProvider(paymentAccount.address, paymentAccount.publicKey, this.defaults);
586
+ return {
587
+ address: paymentAccount.address,
588
+ publicKey: paymentAccount.publicKey,
589
+ xChainType: "BITCOIN"
590
+ };
591
+ }
592
+ async disconnect() {
593
+ this.walletProvider = void 0;
594
+ }
595
+ getWalletProvider() {
596
+ return this.walletProvider;
597
+ }
598
+ recreateWalletProvider(xAccount) {
599
+ if (!xAccount.address || !xAccount.publicKey) return void 0;
600
+ return new BitcoinHanaWalletProvider(xAccount.address, xAccount.publicKey, this.defaults);
601
+ }
602
+ };
419
603
  function getXChainType(xChainId) {
420
604
  if (!xChainId) {
421
605
  return void 0;
@@ -496,7 +680,12 @@ var chainRegistry = {
496
680
  const defaults = getEntryDefaults(
497
681
  walletConfig?.BITCOIN?.chains?.[ChainKeys.BITCOIN_MAINNET]
498
682
  );
499
- return [new UnisatXConnector(defaults), new XverseXConnector(defaults), new OKXXConnector(defaults)];
683
+ return [
684
+ new UnisatXConnector(defaults),
685
+ new XverseXConnector(defaults),
686
+ new OKXXConnector(defaults),
687
+ new BitcoinHanaXConnector(defaults)
688
+ ];
500
689
  },
501
690
  providerManaged: false,
502
691
  createActions: (service, getStore) => ({
@@ -510,27 +699,16 @@ var chainRegistry = {
510
699
  }
511
700
  const address = connection?.xAccount.address;
512
701
  if (!address) throw new Error("Bitcoin address not found");
513
- const addressType = detectBitcoinAddressType(address);
514
- switch (addressType) {
515
- case "P2WPKH":
516
- case "P2TR": {
517
- if (!hasSignBip322(connector)) {
518
- throw new Error(`${connector.id} does not support BIP-322 signing`);
519
- }
520
- return connector.signBip322Message(message);
521
- }
522
- case "P2SH":
523
- case "P2PKH": {
524
- if (!hasSignEcdsa(connector)) {
525
- throw new Error(`${connector.id} does not support ECDSA signing`);
526
- }
527
- return connector.signEcdsaMessage(message);
528
- }
529
- default: {
530
- const _exhaustiveCheck = addressType;
531
- throw new Error(`Unhandled Bitcoin address type: ${_exhaustiveCheck}`);
702
+ if (usesBip322MessageSigning(detectBitcoinAddressType(address))) {
703
+ if (!hasSignBip322(connector)) {
704
+ throw new Error(`${connector.id} does not support BIP-322 signing`);
532
705
  }
706
+ return connector.signBip322Message(message);
707
+ }
708
+ if (!hasSignEcdsa(connector)) {
709
+ throw new Error(`${connector.id} does not support ECDSA signing`);
533
710
  }
711
+ return connector.signEcdsaMessage(message);
534
712
  }
535
713
  }),
536
714
  createWalletProvider: (service, getStore) => {
@@ -803,9 +981,20 @@ var useXWalletStore = create()(
803
981
  }
804
982
  })),
805
983
  {
806
- // key kept as 'xwagmi-store' for backward compat existing users won't lose persisted connections on upgrade
984
+ // key kept as 'xwagmi-store' for backward compat, existing users won't lose persisted connections on upgrade
807
985
  name: "xwagmi-store",
808
- storage: createJSONStorage(() => localStorage),
986
+ // Throw on SSR or when localStorage rejects writes (Safari strict
987
+ // private mode, disabled storage). `createJSONStorage` catches the
988
+ // throw, zustand short-circuits `.persist`, and downstream falls back
989
+ // via `usePersistHydrated`. `setItem` probe is required because modern
990
+ // Safari only throws on writes, not reads.
991
+ storage: createJSONStorage(() => {
992
+ if (typeof window === "undefined") throw new Error("no window");
993
+ const probe = "__sodax_probe__";
994
+ window.localStorage.setItem(probe, "1");
995
+ window.localStorage.removeItem(probe);
996
+ return window.localStorage;
997
+ }),
809
998
  partialize: (state) => ({
810
999
  xConnections: state.xConnections,
811
1000
  userDisconnected: state.userDisconnected
@@ -988,6 +1177,33 @@ function useChainGroups({ order } = {}) {
988
1177
  [enabledChains, xConnections, order]
989
1178
  );
990
1179
  }
1180
+ var NOOP = () => {
1181
+ };
1182
+ function subscribe(onChange) {
1183
+ const api = useXWalletStore.persist;
1184
+ if (!api) return NOOP;
1185
+ const unsubHydrate = api.onHydrate(onChange);
1186
+ const unsubFinish = api.onFinishHydration(onChange);
1187
+ return () => {
1188
+ unsubHydrate();
1189
+ unsubFinish();
1190
+ };
1191
+ }
1192
+ var getSnapshot = () => useXWalletStore.persist?.hasHydrated() ?? true;
1193
+ var getServerSnapshot = () => false;
1194
+ function usePersistHydrated() {
1195
+ return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
1196
+ }
1197
+ function whenPersistReady(cb) {
1198
+ const api = useXWalletStore.persist;
1199
+ if (!api || api.hasHydrated()) {
1200
+ cb();
1201
+ return;
1202
+ }
1203
+ api.onFinishHydration(cb);
1204
+ }
1205
+
1206
+ // src/hooks/useConnectedChains.ts
991
1207
  function buildConnectedChains(xConnections, xConnectorsByChain, isReady = true, order) {
992
1208
  const chains = [];
993
1209
  for (const chainType of ChainTypeArr) {
@@ -1012,22 +1228,10 @@ function buildConnectedChains(xConnections, xConnectorsByChain, isReady = true,
1012
1228
  status: isReady ? "ready" : "loading"
1013
1229
  };
1014
1230
  }
1015
- function subscribeHydration(onChange) {
1016
- const unsubHydrate = useXWalletStore.persist.onHydrate(onChange);
1017
- const unsubFinish = useXWalletStore.persist.onFinishHydration(onChange);
1018
- return () => {
1019
- unsubHydrate();
1020
- unsubFinish();
1021
- };
1022
- }
1023
1231
  function useConnectedChains({ order } = {}) {
1024
1232
  const xConnections = useXConnections();
1025
1233
  const xConnectorsByChain = useXConnectorsByChain();
1026
- const isReady = useSyncExternalStore(
1027
- subscribeHydration,
1028
- () => useXWalletStore.persist.hasHydrated(),
1029
- () => false
1030
- );
1234
+ const isReady = usePersistHydrated();
1031
1235
  return useMemo(
1032
1236
  () => buildConnectedChains(xConnections, xConnectorsByChain, isReady, order),
1033
1237
  [xConnections, xConnectorsByChain, isReady, order]
@@ -1580,6 +1784,4 @@ function useBitcoinXConnectors() {
1580
1784
  }, [xService]);
1581
1785
  }
1582
1786
 
1583
- export { BitcoinXConnector, BitcoinXService, OKXXConnector, UnisatXConnector, WalletConfigProvider, XverseXConnector, chainRegistry, getXChainType, getXService, useBatchConnect, useBatchDisconnect, useBitcoinXConnectors, useChainGroups, useConnectedChains, useConnectionFlow, useEnabledChainTypes, useEnabledChains, useEvmSwitchChain, useIsChainEnabled, useIsWalletInstalled, useWalletConfig, useWalletModal, useWalletProvider, useXAccount, useXAccounts, useXConnect, useXConnection, useXConnections, useXConnectors, useXConnectorsByChain, useXDisconnect, useXService, useXServices, useXSignMessage, useXWalletStore };
1584
- //# sourceMappingURL=chunk-PLCA4ZDJ.mjs.map
1585
- //# sourceMappingURL=chunk-PLCA4ZDJ.mjs.map
1787
+ export { BitcoinHanaXConnector, BitcoinXConnector, BitcoinXService, OKXXConnector, UnisatXConnector, WalletConfigProvider, XverseXConnector, chainRegistry, getXChainType, getXService, useBatchConnect, useBatchDisconnect, useBitcoinXConnectors, useChainGroups, useConnectedChains, useConnectionFlow, useEnabledChainTypes, useEnabledChains, useEvmSwitchChain, useIsChainEnabled, useIsWalletInstalled, usePersistHydrated, useWalletConfig, useWalletModal, useWalletProvider, useXAccount, useXAccounts, useXConnect, useXConnection, useXConnections, useXConnectors, useXConnectorsByChain, useXDisconnect, useXService, useXServices, useXSignMessage, useXWalletStore, whenPersistReady };
@@ -1,11 +1,12 @@
1
- import { getRpcUrl, getWagmiChainId, isNativeToken } from './chunk-NY7U7OJW.mjs';
2
- import { XService, XConnector } from './chunk-X2MHIWXO.mjs';
1
+ import { getRpcUrl, getWagmiChainId, isNativeToken } from './chunk-7V7O3Q7Y.mjs';
2
+ import { XService, XConnector } from './chunk-IFXZQW4C.mjs';
3
3
  import { ChainKeys } from '@sodax/types';
4
- import { defineChain, erc20Abi } from 'viem';
4
+ import { erc20Abi, defineChain } from 'viem';
5
5
  import { getPublicClient } from 'wagmi/actions';
6
- import { createConfig, createStorage, http, cookieStorage } from 'wagmi';
7
- import { mainnet, avalanche, arbitrum, base, bsc, sonic, optimism, polygon, lightlinkPhoenix, kaia, redbellyMainnet } from 'wagmi/chains';
6
+ import { createConfig, createStorage, cookieStorage, http } from 'wagmi';
7
+ import { mainnet, avalanche, arbitrum, base, bsc, sonic, optimism, polygon, lightlinkPhoenix, kaia, redbellyMainnet, hedera } from 'wagmi/chains';
8
8
 
9
+ var HEDERA_NATIVE_BALANCE_SCALE = 10n ** 10n;
9
10
  var hyper = /* @__PURE__ */ defineChain({
10
11
  id: 999,
11
12
  name: "HyperEVM",
@@ -44,10 +45,17 @@ var createWagmiConfig = (evmChains, options) => {
44
45
  hyper,
45
46
  lightlinkPhoenix,
46
47
  kaia,
47
- redbellyMainnet
48
+ redbellyMainnet,
49
+ hedera
48
50
  ],
49
51
  connectors: options?.connectors ?? [],
50
- ssr: options?.ssr,
52
+ // NOTE: wagmi's `ssr` is a hydration-timing flag, not an "is host app SSR"
53
+ // flag. `true` defers `Hydrate.onMount()` into `useEffect` (safe for both
54
+ // CSR and SSR); `false` runs it in render and trips React's "setState
55
+ // during render" warning on subscribers like `EvmHydrator`. Default to
56
+ // `true` so direct callers of `createWagmiConfig` stay safe — only pass
57
+ // `false` if you have a specific reason. See issue #129.
58
+ ssr: options?.ssr ?? true,
51
59
  transports: {
52
60
  [mainnet.id]: http(getRpcUrl(evmChains?.[ChainKeys.ETHEREUM_MAINNET])),
53
61
  [avalanche.id]: http(getRpcUrl(evmChains?.[ChainKeys.AVALANCHE_MAINNET])),
@@ -60,7 +68,8 @@ var createWagmiConfig = (evmChains, options) => {
60
68
  [hyper.id]: http(getRpcUrl(evmChains?.[ChainKeys.HYPEREVM_MAINNET])),
61
69
  [lightlinkPhoenix.id]: http(getRpcUrl(evmChains?.[ChainKeys.LIGHTLINK_MAINNET])),
62
70
  [redbellyMainnet.id]: http(getRpcUrl(evmChains?.[ChainKeys.REDBELLY_MAINNET])),
63
- [kaia.id]: http(getRpcUrl(evmChains?.[ChainKeys.KAIA_MAINNET]))
71
+ [kaia.id]: http(getRpcUrl(evmChains?.[ChainKeys.KAIA_MAINNET])),
72
+ [hedera.id]: http(getRpcUrl(evmChains?.[ChainKeys.HEDERA_MAINNET]))
64
73
  },
65
74
  storage: createStorage({
66
75
  storage: cookieStorage,
@@ -104,7 +113,11 @@ var EvmXService = class _EvmXService extends XService {
104
113
  if (!this.wagmiConfig) return 0n;
105
114
  const chainId = getWagmiChainId(xToken.chainKey);
106
115
  if (isNativeToken(xToken)) {
107
- return this._getChainBalance(address, chainId);
116
+ const balance = await this._getChainBalance(address, chainId);
117
+ if (xToken.chainKey === ChainKeys.HEDERA_MAINNET) {
118
+ return balance / HEDERA_NATIVE_BALANCE_SCALE;
119
+ }
120
+ return balance;
108
121
  }
109
122
  throw new Error(`Unsupported token: ${xToken.symbol}`);
110
123
  }
@@ -182,5 +195,3 @@ var EvmXConnector = class extends XConnector {
182
195
  };
183
196
 
184
197
  export { EvmXConnector, EvmXService, createWagmiConfig };
185
- //# sourceMappingURL=chunk-E5IAZ7E6.mjs.map
186
- //# sourceMappingURL=chunk-E5IAZ7E6.mjs.map
@@ -1,10 +1,10 @@
1
- import { XService, XConnector } from './chunk-X2MHIWXO.mjs';
1
+ import { XService, XConnector } from './chunk-IFXZQW4C.mjs';
2
2
  import { getNetworkEndpoints, Network } from '@injectivelabs/networks';
3
3
  import { IndexerGrpcAccountPortfolioApi, ChainGrpcWasmApi, getInjectiveAddress } from '@injectivelabs/sdk-ts';
4
4
  import { ChainId } from '@injectivelabs/ts-types';
5
5
  import { MsgBroadcaster } from '@injectivelabs/wallet-core';
6
6
  import { mainnet } from 'wagmi/chains';
7
- import { WalletStrategy } from '@injectivelabs/wallet-strategy';
7
+ import { WalletStrategy } from '@sodax/libs/injective/wallet-strategy';
8
8
  import { isCosmosBrowserWallet, isEvmBrowserWallet } from '@injectivelabs/wallet-base';
9
9
  import { isCosmosWalletInstalled } from '@injectivelabs/wallet-cosmos';
10
10
 
@@ -121,5 +121,3 @@ var InjectiveXConnector = class extends XConnector {
121
121
  };
122
122
 
123
123
  export { InjectiveXConnector, InjectiveXService };
124
- //# sourceMappingURL=chunk-BKJB527E.mjs.map
125
- //# sourceMappingURL=chunk-BKJB527E.mjs.map
@@ -30,5 +30,3 @@ var WALLET_METADATA = {
30
30
  };
31
31
 
32
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 };
33
- //# sourceMappingURL=chunk-MXZVF5HR.mjs.map
34
- //# sourceMappingURL=chunk-MXZVF5HR.mjs.map
@@ -1,7 +1,6 @@
1
- import { XService, XConnector } from './chunk-X2MHIWXO.mjs';
2
- import { fetchCallReadOnlyFunction, Cl } from '@stacks/transactions';
3
- import { networkFrom } from '@stacks/network';
4
- import { request, disconnect } from '@stacks/connect';
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';
5
4
  import { useMemo } from 'react';
6
5
 
7
6
  var StacksXService = class _StacksXService extends XService {
@@ -19,6 +18,12 @@ var StacksXService = class _StacksXService extends XService {
19
18
  }
20
19
  return _StacksXService.instance;
21
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
+ */
22
27
  async getBalance(address, xToken) {
23
28
  if (!address) return 0n;
24
29
  if (xToken.symbol === "STX") {
@@ -55,6 +60,7 @@ var StacksXService = class _StacksXService extends XService {
55
60
  }
56
61
  };
57
62
  function getProviderFromId(id) {
63
+ if (typeof window === "undefined") return void 0;
58
64
  return id.split(".").reduce((acc, part) => acc?.[part], window);
59
65
  }
60
66
  var StacksXConnector = class extends XConnector {
@@ -79,6 +85,7 @@ var StacksXConnector = class extends XConnector {
79
85
  }
80
86
  return {
81
87
  address: stxAddress.address,
88
+ publicKey: stxAddress.publicKey,
82
89
  xChainType: this.xChainType
83
90
  };
84
91
  }
@@ -136,5 +143,3 @@ function useStacksXConnectors() {
136
143
  }
137
144
 
138
145
  export { STACKS_PROVIDERS, StacksXConnector, StacksXService, useStacksXConnectors };
139
- //# sourceMappingURL=chunk-PJLEJVAU.mjs.map
140
- //# sourceMappingURL=chunk-PJLEJVAU.mjs.map
@@ -0,0 +1 @@
1
+
@@ -29,5 +29,3 @@ function assertSuiProviderShape(caller, client, wallet, account) {
29
29
  }
30
30
 
31
31
  export { assert, assertSuiProviderShape, hasBooleanProperty, hasFunctionProperty, hasOptionalStringProperty, hasStringProperty, isRecord };
32
- //# sourceMappingURL=chunk-MAQ47Q52.mjs.map
33
- //# sourceMappingURL=chunk-MAQ47Q52.mjs.map