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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/README.md +103 -145
  2. package/ai-exported/AGENTS.md +122 -0
  3. package/ai-exported/integration/README.md +102 -0
  4. package/ai-exported/integration/ai-rules.md +136 -0
  5. package/ai-exported/integration/architecture.md +181 -0
  6. package/ai-exported/integration/examples/01-minimal-evm.tsx +75 -0
  7. package/ai-exported/integration/examples/02-multi-chain-modal.tsx +169 -0
  8. package/ai-exported/integration/examples/03-nextjs-app-router.tsx +99 -0
  9. package/ai-exported/integration/examples/04-walletconnect-setup.tsx +89 -0
  10. package/ai-exported/integration/examples/README.md +29 -0
  11. package/ai-exported/integration/recipes/batch-operations.md +223 -0
  12. package/ai-exported/integration/recipes/bridge-to-sdk.md +164 -0
  13. package/ai-exported/integration/recipes/chain-detection.md +254 -0
  14. package/ai-exported/integration/recipes/connect-button.md +156 -0
  15. package/ai-exported/integration/recipes/multi-chain-modal.md +199 -0
  16. package/ai-exported/integration/recipes/setup.md +158 -0
  17. package/ai-exported/integration/recipes/sign-message.md +137 -0
  18. package/ai-exported/integration/recipes/sub-path-imports.md +95 -0
  19. package/ai-exported/integration/recipes/switch-chain.md +141 -0
  20. package/ai-exported/integration/recipes/walletconnect-setup.md +139 -0
  21. package/ai-exported/integration/reference/api-surface.md +175 -0
  22. package/ai-exported/integration/reference/chain-support.md +78 -0
  23. package/ai-exported/integration/reference/connectors.md +74 -0
  24. package/ai-exported/integration/reference/hooks.md +204 -0
  25. package/ai-exported/integration/reference/wallet-brands.md +106 -0
  26. package/ai-exported/migration/README.md +49 -0
  27. package/ai-exported/migration/ai-rules.md +144 -0
  28. package/ai-exported/migration/breaking-changes.md +305 -0
  29. package/ai-exported/migration/checklist.md +159 -0
  30. package/ai-exported/migration/recipes/connect-button.md +166 -0
  31. package/ai-exported/migration/recipes/multi-chain-modal.md +244 -0
  32. package/ai-exported/migration/recipes/ssr-setup.md +162 -0
  33. package/ai-exported/migration/recipes/walletconnect-migration.md +168 -0
  34. package/ai-exported/migration/reference/components.md +73 -0
  35. package/ai-exported/migration/reference/config.md +307 -0
  36. package/ai-exported/migration/reference/hooks.md +278 -0
  37. package/ai-exported/migration/reference/imports.md +157 -0
  38. package/dist/XConnector-B9YQTVJ4.d.ts +146 -0
  39. package/dist/chunk-2BOUGCJ7.mjs +150 -0
  40. package/dist/chunk-2BOUGCJ7.mjs.map +1 -0
  41. package/dist/chunk-66BAUK56.mjs +202 -0
  42. package/dist/chunk-66BAUK56.mjs.map +1 -0
  43. package/dist/chunk-7ULB6DW4.mjs +102 -0
  44. package/dist/chunk-7ULB6DW4.mjs.map +1 -0
  45. package/dist/chunk-BKJB527E.mjs +125 -0
  46. package/dist/chunk-BKJB527E.mjs.map +1 -0
  47. package/dist/chunk-BXJLBR4G.mjs +88 -0
  48. package/dist/chunk-BXJLBR4G.mjs.map +1 -0
  49. package/dist/chunk-E5IAZ7E6.mjs +186 -0
  50. package/dist/chunk-E5IAZ7E6.mjs.map +1 -0
  51. package/dist/chunk-MAQ47Q52.mjs +33 -0
  52. package/dist/chunk-MAQ47Q52.mjs.map +1 -0
  53. package/dist/chunk-MXZVF5HR.mjs +34 -0
  54. package/dist/chunk-MXZVF5HR.mjs.map +1 -0
  55. package/dist/chunk-N5A2TMF6.mjs +33 -0
  56. package/dist/chunk-N5A2TMF6.mjs.map +1 -0
  57. package/dist/chunk-NY7U7OJW.mjs +64 -0
  58. package/dist/chunk-NY7U7OJW.mjs.map +1 -0
  59. package/dist/chunk-PJLEJVAU.mjs +140 -0
  60. package/dist/chunk-PJLEJVAU.mjs.map +1 -0
  61. package/dist/chunk-PLCA4ZDJ.mjs +1585 -0
  62. package/dist/chunk-PLCA4ZDJ.mjs.map +1 -0
  63. package/dist/chunk-TZMKDXFA.mjs +3 -0
  64. package/dist/chunk-TZMKDXFA.mjs.map +1 -0
  65. package/dist/chunk-X2MHIWXO.mjs +100 -0
  66. package/dist/chunk-X2MHIWXO.mjs.map +1 -0
  67. package/dist/chunk-XZ7CHO2S.mjs +41 -0
  68. package/dist/chunk-XZ7CHO2S.mjs.map +1 -0
  69. package/dist/config-OlnzyEUE.d.ts +146 -0
  70. package/dist/index.cjs +2784 -1594
  71. package/dist/index.cjs.map +1 -1
  72. package/dist/index.d.ts +768 -1498
  73. package/dist/index.mjs +463 -2004
  74. package/dist/index.mjs.map +1 -1
  75. package/dist/xchains/bitcoin/index.cjs +1927 -0
  76. package/dist/xchains/bitcoin/index.cjs.map +1 -0
  77. package/dist/xchains/bitcoin/index.d.ts +125 -0
  78. package/dist/xchains/bitcoin/index.mjs +16 -0
  79. package/dist/xchains/bitcoin/index.mjs.map +1 -0
  80. package/dist/xchains/evm/index.cjs +316 -0
  81. package/dist/xchains/evm/index.cjs.map +1 -0
  82. package/dist/xchains/evm/index.d.ts +39 -0
  83. package/dist/xchains/evm/index.mjs +5 -0
  84. package/dist/xchains/evm/index.mjs.map +1 -0
  85. package/dist/xchains/icon/index.cjs +311 -0
  86. package/dist/xchains/icon/index.cjs.map +1 -0
  87. package/dist/xchains/icon/index.d.ts +37 -0
  88. package/dist/xchains/icon/index.mjs +7 -0
  89. package/dist/xchains/icon/index.mjs.map +1 -0
  90. package/dist/xchains/injective/index.cjs +223 -0
  91. package/dist/xchains/injective/index.cjs.map +1 -0
  92. package/dist/xchains/injective/index.d.ts +35 -0
  93. package/dist/xchains/injective/index.mjs +5 -0
  94. package/dist/xchains/injective/index.mjs.map +1 -0
  95. package/dist/xchains/near/index.cjs +190 -0
  96. package/dist/xchains/near/index.cjs.map +1 -0
  97. package/dist/xchains/near/index.d.ts +34 -0
  98. package/dist/xchains/near/index.mjs +6 -0
  99. package/dist/xchains/near/index.mjs.map +1 -0
  100. package/dist/xchains/solana/index.cjs +186 -0
  101. package/dist/xchains/solana/index.cjs.map +1 -0
  102. package/dist/xchains/solana/index.d.ts +26 -0
  103. package/dist/xchains/solana/index.mjs +7 -0
  104. package/dist/xchains/solana/index.mjs.map +1 -0
  105. package/dist/xchains/stacks/index.cjs +240 -0
  106. package/dist/xchains/stacks/index.cjs.map +1 -0
  107. package/dist/xchains/stacks/index.d.ts +36 -0
  108. package/dist/xchains/stacks/index.mjs +5 -0
  109. package/dist/xchains/stacks/index.mjs.map +1 -0
  110. package/dist/xchains/stellar/index.cjs +322 -0
  111. package/dist/xchains/stellar/index.cjs.map +1 -0
  112. package/dist/xchains/stellar/index.d.ts +44 -0
  113. package/dist/xchains/stellar/index.mjs +6 -0
  114. package/dist/xchains/stellar/index.mjs.map +1 -0
  115. package/dist/xchains/sui/index.cjs +248 -0
  116. package/dist/xchains/sui/index.cjs.map +1 -0
  117. package/dist/xchains/sui/index.d.ts +37 -0
  118. package/dist/xchains/sui/index.mjs +7 -0
  119. package/dist/xchains/sui/index.mjs.map +1 -0
  120. package/docs/ADDING_A_NEW_CHAIN.md +440 -0
  121. package/docs/ARCHITECTURE.md +291 -0
  122. package/docs/BATCH_OPERATIONS.md +267 -0
  123. package/docs/CHAIN_DETECTION.md +216 -0
  124. package/docs/CONFIGURE_PROVIDER.md +360 -0
  125. package/docs/CONNECTORS.md +247 -0
  126. package/docs/CONNECT_FLOW.md +276 -0
  127. package/docs/EVM_SWITCH_CHAIN.md +161 -0
  128. package/docs/SIGN_MESSAGE.md +213 -0
  129. package/docs/SUB_PATH_EXPORTS.md +246 -0
  130. package/docs/WALLETCONNECT.md +154 -0
  131. package/docs/WALLET_MODAL.md +331 -0
  132. package/docs/WALLET_PROVIDER_BRIDGE.md +226 -0
  133. package/package.json +37 -12
  134. package/skills/SKILLS.md +84 -0
  135. package/skills/bridge-to-sdk.md +148 -0
  136. package/skills/connect-button.md +116 -0
  137. package/skills/evm-only-walletconnect.md +111 -0
  138. package/skills/multi-chain-modal.md +178 -0
  139. package/skills/setup.md +107 -0
  140. package/dist/index.d.cts +0 -1579
  141. package/src/Hydrate.ts +0 -65
  142. package/src/SodaxWalletProvider.tsx +0 -97
  143. package/src/actions/getXChainType.ts +0 -8
  144. package/src/actions/getXService.ts +0 -33
  145. package/src/actions/index.ts +0 -2
  146. package/src/assets/wallets/hana.svg +0 -6
  147. package/src/assets/wallets/havah.svg +0 -76
  148. package/src/assets/wallets/keplr.svg +0 -30
  149. package/src/assets/wallets/metamask.svg +0 -60
  150. package/src/assets/wallets/phantom.svg +0 -4
  151. package/src/assets/wallets/sui.svg +0 -20
  152. package/src/core/XConnector.ts +0 -54
  153. package/src/core/XService.ts +0 -85
  154. package/src/core/index.ts +0 -2
  155. package/src/hooks/index.ts +0 -11
  156. package/src/hooks/useEthereumChainId.ts +0 -44
  157. package/src/hooks/useEvmSwitchChain.ts +0 -91
  158. package/src/hooks/useWalletProvider.ts +0 -206
  159. package/src/hooks/useXAccount.ts +0 -51
  160. package/src/hooks/useXAccounts.ts +0 -56
  161. package/src/hooks/useXBalances.ts +0 -65
  162. package/src/hooks/useXConnect.ts +0 -118
  163. package/src/hooks/useXConnection.ts +0 -72
  164. package/src/hooks/useXConnectors.ts +0 -72
  165. package/src/hooks/useXDisconnect.ts +0 -73
  166. package/src/hooks/useXService.ts +0 -8
  167. package/src/hooks/useXSignMessage.ts +0 -82
  168. package/src/index.ts +0 -19
  169. package/src/types/index.ts +0 -22
  170. package/src/useXWagmiStore.ts +0 -116
  171. package/src/utils/index.ts +0 -21
  172. package/src/xchains/bitcoin/BitcoinXConnector.ts +0 -34
  173. package/src/xchains/bitcoin/BitcoinXService.ts +0 -40
  174. package/src/xchains/bitcoin/OKXXConnector.ts +0 -117
  175. package/src/xchains/bitcoin/UnisatXConnector.ts +0 -117
  176. package/src/xchains/bitcoin/XverseXConnector.ts +0 -232
  177. package/src/xchains/bitcoin/index.ts +0 -7
  178. package/src/xchains/bitcoin/useBitcoinXConnectors.ts +0 -14
  179. package/src/xchains/evm/EvmXConnector.ts +0 -27
  180. package/src/xchains/evm/EvmXService.ts +0 -211
  181. package/src/xchains/evm/index.ts +0 -3
  182. package/src/xchains/icon/IconHanaXConnector.ts +0 -39
  183. package/src/xchains/icon/IconXService.ts +0 -117
  184. package/src/xchains/icon/actions.ts +0 -28
  185. package/src/xchains/icon/iconex/index.tsx +0 -46
  186. package/src/xchains/icon/index.ts +0 -2
  187. package/src/xchains/injective/InjectiveXConnector.ts +0 -60
  188. package/src/xchains/injective/InjectiveXService.ts +0 -62
  189. package/src/xchains/injective/actions.ts +0 -32
  190. package/src/xchains/injective/index.ts +0 -2
  191. package/src/xchains/near/NearXConnector.ts +0 -42
  192. package/src/xchains/near/NearXService.ts +0 -46
  193. package/src/xchains/near/useNearXConnectors.ts +0 -23
  194. package/src/xchains/solana/SolanaXConnector.ts +0 -26
  195. package/src/xchains/solana/SolanaXService.ts +0 -46
  196. package/src/xchains/solana/index.ts +0 -2
  197. package/src/xchains/stacks/StacksXConnector.ts +0 -63
  198. package/src/xchains/stacks/StacksXService.ts +0 -59
  199. package/src/xchains/stacks/constants.ts +0 -42
  200. package/src/xchains/stacks/index.ts +0 -4
  201. package/src/xchains/stacks/useStacksXConnectors.ts +0 -7
  202. package/src/xchains/stellar/CustomSorobanServer.ts +0 -93
  203. package/src/xchains/stellar/StellarWalletsKitXConnector.ts +0 -53
  204. package/src/xchains/stellar/StellarXService.ts +0 -93
  205. package/src/xchains/stellar/actions.ts +0 -24
  206. package/src/xchains/stellar/index.tsx +0 -2
  207. package/src/xchains/stellar/useStellarXConnectors.ts +0 -21
  208. package/src/xchains/stellar/utils.ts +0 -49
  209. package/src/xchains/sui/SuiXConnector.ts +0 -28
  210. package/src/xchains/sui/SuiXService.ts +0 -66
  211. package/src/xchains/sui/index.ts +0 -2
@@ -0,0 +1,49 @@
1
+ # Migration: v1 → v2 (Human-readable overview)
2
+
3
+ This folder documents how to migrate an app from v1 to v2 of `@sodax/wallet-sdk-react`. The package name did not change — the breaking changes are in the API surface (provider config, hook signatures, store name, chain class imports). It is the **human-facing** entry point for migration. If you are a coding agent, read [`ai-rules.md`](./ai-rules.md) first.
4
+
5
+ ---
6
+
7
+ ## What changed at a high level
8
+
9
+ v2 is a near-rewrite of v1 with a focus on three goals:
10
+
11
+ 1. **Configurable chain opt-in** — v1 always mounted every chain adapter. v2 lets you opt in per chain by including only the slots you need on `SodaxWalletConfig`.
12
+ 2. **Single source of truth for chain config** — v1 spread chain config across `rpcConfig`, `options`, and `initialState`. v2 collapses these into one `config` object on `SodaxWalletProvider`.
13
+ 3. **Store-first hooks** — v2 hooks all read from a central Zustand store; no chain-specific React context coupling. This makes hooks composable and testable in isolation.
14
+
15
+ The persisted localStorage key (`xwagmi-store`) is **unchanged** — existing user connections survive the migration boundary.
16
+
17
+ > Full prose on motivations and behavior changes lives in [`breaking-changes.md`](./breaking-changes.md).
18
+
19
+ ---
20
+
21
+ ## Read order
22
+
23
+ If you are migrating by hand, read in this order:
24
+
25
+ 1. [`breaking-changes.md`](./breaking-changes.md) — every breaking change with the WHY behind it.
26
+ 2. [`reference/imports.md`](./reference/imports.md) — package and path renames (mechanical).
27
+ 3. [`reference/config.md`](./reference/config.md) — `SodaxWalletProvider` config shape (this is the biggest single change).
28
+ 4. [`reference/hooks.md`](./reference/hooks.md) — hook signature and rename map.
29
+ 5. [`reference/components.md`](./reference/components.md) — component / provider renames.
30
+ 6. [`recipes/`](./recipes/) — paired before/after for common patterns (connect button, multi-chain modal, SSR, WalletConnect).
31
+ 7. [`checklist.md`](./checklist.md) — final verification pass; tick each item before declaring done.
32
+
33
+ If you are letting a coding agent drive the migration, point it at [`ai-rules.md`](./ai-rules.md) — that file gives the agent its workflow, stop conditions, and verification protocol.
34
+
35
+ ---
36
+
37
+ ## What is NOT covered here
38
+
39
+ - **Other SODAX packages** (`@sodax/sdk`, `@sodax/dapp-kit`). They have their own migration docs in their respective `ai-exported/` folders.
40
+ - **Behavioral migration of business logic** that isn't tied to wallet hooks — out of scope.
41
+ - **App framework upgrades** (Next.js, Vite versions) — out of scope.
42
+
43
+ ---
44
+
45
+ ## Getting help
46
+
47
+ If you hit a v1 pattern not covered in `reference/` or `recipes/`, please [open an issue](https://github.com/icon-project/sodax-sdks/issues) with the v1 code snippet — we'll add it to the docs.
48
+
49
+ For internal SODAX maintainers: see `../CLAUDE.md` for architecture context.
@@ -0,0 +1,144 @@
1
+ # AI Rules — v1 → v2 Migration
2
+
3
+ You are migrating a user's app from v1 to v2 of `@sodax/wallet-sdk-react`. The package name did not change — detect v1 by import surface (`useXWagmiStore`, positional hook args, `rpcConfig`/`options`/`initialState` props on `SodaxWalletProvider`, concrete chain class imports from the barrel). Follow this protocol exactly.
4
+
5
+ ---
6
+
7
+ ## Workflow (do these in order)
8
+
9
+ ### 1. Survey
10
+
11
+ Before changing anything, survey the user's project:
12
+
13
+ ```bash
14
+ # v1 store usage
15
+ grep -rn "useXWagmiStore" <user-src>
16
+
17
+ # v1 provider props (rpcConfig / options / initialState)
18
+ grep -rn "SodaxWalletProvider" <user-src> -A 5 | grep -E "rpcConfig|initialState|options="
19
+
20
+ # v1 positional hook args (e.g. useXAccount('EVM'))
21
+ grep -rnE "useXAccount\(['\"]" <user-src>
22
+ grep -rnE "useXConnectors\(['\"]" <user-src>
23
+ grep -rnE "useXConnection\(['\"]" <user-src>
24
+ grep -rnE "useXService\(['\"]" <user-src>
25
+ grep -rnE "useWalletProvider\(['\"]" <user-src>
26
+
27
+ # v1 concrete chain class imports from the barrel
28
+ grep -rnE "from '@sodax/wallet-sdk-react'" <user-src> | grep -E "XService|XConnector"
29
+ ```
30
+
31
+ Build a list of every file that uses a v1 pattern. Show this list to the user before proceeding.
32
+
33
+ ### 2. Bump the package version
34
+
35
+ Update `@sodax/wallet-sdk-react` to the latest v2 release in the user's `package.json`. Run install. **Do not edit any source files yet** — keep TypeScript broken so you can use compiler errors as a worklist.
36
+
37
+ ### 3. Migrate the provider first
38
+
39
+ Always migrate `SodaxWalletProvider` (or v1's `XWagmiProviders`) before touching consumer files. The config shape is the biggest change — see [`reference/config.md`](./reference/config.md) and [`recipes/`](./recipes/) for the new pattern. Without a working provider, hooks will fail at runtime even if types pass.
40
+
41
+ ### 4. Run typecheck, use errors as worklist
42
+
43
+ ```bash
44
+ pnpm checkTs
45
+ ```
46
+
47
+ For each error mentioning `@sodax/wallet-sdk-react` or a v1 hook name:
48
+
49
+ 1. Look up the symbol in [`reference/imports.md`](./reference/imports.md), [`reference/hooks.md`](./reference/hooks.md), [`reference/config.md`](./reference/config.md), or [`reference/components.md`](./reference/components.md).
50
+ 2. If found, apply the mechanical replacement.
51
+ 3. If not found, **stop and ask the user**. Do not invent a migration.
52
+
53
+ ### 5. Apply recipes for non-mechanical changes
54
+
55
+ Some patterns require structural rewrites, not just symbol swaps. Use the matching recipe file:
56
+
57
+ - Connect button → [`recipes/connect-button.md`](./recipes/connect-button.md)
58
+ - Multi-chain modal → [`recipes/multi-chain-modal.md`](./recipes/multi-chain-modal.md)
59
+ - Next.js SSR setup → [`recipes/ssr-setup.md`](./recipes/ssr-setup.md)
60
+ - WalletConnect → [`recipes/walletconnect-migration.md`](./recipes/walletconnect-migration.md)
61
+
62
+ ### 6. Verify with the checklist
63
+
64
+ Loop through every item in [`checklist.md`](./checklist.md). Each item is machine-checkable (most are `grep` commands). Do not skip items. Report results back to the user.
65
+
66
+ ---
67
+
68
+ ## DO
69
+
70
+ - **DO** read `migration/breaking-changes.md` once at the start to understand the WHY behind changes. This helps you handle ambiguous user code.
71
+ - **DO** preserve user comments, formatting, and unrelated code. Only touch what the migration requires.
72
+ - **DO** update one file at a time, then re-run `pnpm checkTs` to confirm progress.
73
+ - **DO** prefer the official `recipes/` over inventing your own structural rewrite.
74
+ - **DO** treat `reference/*.md` as the only source of truth for symbol mappings. If a mapping is missing, it's a docs gap — flag it.
75
+ - **DO** explicitly check whether the user's project is Next.js (App Router or Pages) before touching providers — SSR config differs.
76
+
77
+ ---
78
+
79
+ ## DO NOT
80
+
81
+ - **DO NOT** delete v1 imports until the corresponding v2 imports are added and the file typechecks.
82
+ - **DO NOT** rename user files, even if v1 file names look outdated. Keep file paths stable so the user's git history stays clean.
83
+ - **DO NOT** modify tests until source migration is complete — wait for green typecheck first, then update tests as a separate pass.
84
+ - **DO NOT** "improve" surrounding code (refactor, restyle, add error handling, change variable names). Only apply migration changes.
85
+ - **DO NOT** assume v1 prop shapes from memory — always verify against [`reference/config.md`](./reference/config.md). v1 had several optional fields whose defaults differ from v2.
86
+ - **DO NOT** silently drop user features. If v1 used `XWagmiProviders` with `initialState` and v2 has no equivalent, **stop and ask** how to preserve that state initialization.
87
+ - **DO NOT** change the persisted localStorage key (`xwagmi-store`). User connections will be lost across the migration boundary if you do.
88
+
89
+ ---
90
+
91
+ ## Stop conditions (defer to user)
92
+
93
+ Stop and ask the user before continuing if you encounter any of the following. These cannot be migrated mechanically:
94
+
95
+ | Signal | Why stop |
96
+ |---|---|
97
+ | Custom `XConnector` subclass in user code | v1 and v2 have different abstract method signatures. User must port manually. |
98
+ | Custom `XService` subclass in user code | Same as above. |
99
+ | User reads from `useXWagmiStore` with a selector touching `setXConnection`, `unsetXConnection`, or any v2-internal field (`enabledChains`, `walletProviders`, `chainActions`, …) | These are not part of the v2 public API. Agent must replace direct store reads with public hooks (`useXServices`, `useXConnections`, etc. — see [`reference/imports.md`](./reference/imports.md) § "Store hook removed"). For mutations the user must adopt `useXConnect` / `useXDisconnect` — confirm before substituting. |
100
+ | User passes `rpcConfig`, `options`, or `initialState` to the v1 provider | These are removed in v2. Migration target is the new `config` object. Verify what behavior the user wants preserved. |
101
+ | Test files that mock `XService` or `XConnector` | Mock surface differs. Tests must be updated by hand with the user's intent in mind. |
102
+ | `apps/wallet-modal-example` is referenced | This is internal SODAX scaffolding, not for end users. |
103
+ | User explicitly says "don't change behavior X" | Some v2 changes are intentional behavior shifts (e.g. EVM = single connection across all networks). Confirm before forcing v1 behavior back. |
104
+
105
+ When stopping, **quote the file/line** of the offending code and present the user with concrete options.
106
+
107
+ ---
108
+
109
+ ## Verification protocol (after every change)
110
+
111
+ ```bash
112
+ # 1. Type check
113
+ pnpm checkTs
114
+
115
+ # 2. Verify no v1 patterns remain
116
+ grep -rn "useXWagmiStore\|useXWalletStore" <user-src> # expect empty (v2 barrel doesn't export the store hook under either name — all call sites must use public hooks)
117
+ grep -rnE "SodaxWalletProvider[^>]*\b(rpcConfig|initialState|options)\s*=" <user-src> # expect empty
118
+ grep -rnE "useXAccount\(['\"]" <user-src> # expect empty
119
+ grep -rnE "useXConnectors\(['\"]" <user-src> # expect empty
120
+ grep -rnE "useXConnection\(['\"]" <user-src> # expect empty
121
+
122
+ # 3. Verify v2 provider is mounted with config prop
123
+ grep -rnE "SodaxWalletProvider[^>]*\bconfig\s*=" <user-src> # expect at least one match in app entry
124
+
125
+ # 4. Verify QueryClientProvider wraps SodaxWalletProvider (v2 no longer mounts QueryClient internally)
126
+ # (manual — open the provider file, confirm <QueryClientProvider> wraps <SodaxWalletProvider>)
127
+ ```
128
+
129
+ If all four pass and the [`checklist.md`](./checklist.md) is complete, the migration is done.
130
+
131
+ ---
132
+
133
+ ## Done criteria
134
+
135
+ The migration is complete when:
136
+
137
+ - [ ] `pnpm checkTs` exits clean.
138
+ - [ ] No `useXWagmiStore` or `useXWalletStore` imports remain (v2 does not export the store hook — every call site must use public hooks like `useXServices` / `useXConnections`).
139
+ - [ ] No positional hook args remain (`useXAccount('EVM')` etc).
140
+ - [ ] `SodaxWalletProvider` is mounted with a v2-shaped `config` prop, wrapped by `QueryClientProvider`.
141
+ - [ ] All items in [`checklist.md`](./checklist.md) are checked.
142
+ - [ ] The user has confirmed the connect/disconnect flow works in their dev environment.
143
+
144
+ Do not declare the migration done before all six are true.
@@ -0,0 +1,305 @@
1
+ # Breaking Changes: v1 → v2
2
+
3
+ This is the **single source of truth** for behavior and API changes between v1 and v2 of `@sodax/wallet-sdk-react`. The reference files (`imports.md`, `hooks.md`, `config.md`, `components.md`) are **lookup tables** derived from the changes here — they do not duplicate the prose.
4
+
5
+ ## Table of contents
6
+
7
+ 1. [`SodaxWalletProvider` props (largest change)](#1-sodaxwalletprovider-props-largest-change)
8
+ 2. [`QueryClientProvider` is no longer mounted internally](#2-queryclientprovider-is-no-longer-mounted-internally)
9
+ 3. [Hooks now take an options object, not positional args](#3-hooks-now-take-an-options-object-not-positional-args)
10
+ 4. [Store hook removed from the public API](#4-store-hook-removed-from-the-public-api)
11
+ 5. [Concrete chain classes moved behind sub-path imports](#5-concrete-chain-classes-moved-behind-sub-path-imports)
12
+ 6. [Chain-type opt-in (mounting behavior)](#6-chain-type-opt-in-mounting-behavior)
13
+ 7. [EVM = single connection across every configured EVM network](#7-evm--single-connection-across-every-configured-evm-network)
14
+ 8. [New: WalletConnect support for EVM](#8-new-walletconnect-support-for-evm)
15
+ 9. [New: headless wallet modal primitives](#9-new-headless-wallet-modal-primitives)
16
+ 10. [Removed: `useXBalances`](#10-removed-usexbalances)
17
+ 11. [`useEvmSwitchChain` reshaped](#11-useevmswitchchain-reshaped)
18
+ 12. [`SodaxWalletProvider` freezes config on first render](#12-sodaxwalletprovider-freezes-config-on-first-render)
19
+
20
+ What did NOT change → [bottom of file](#what-did-not-change).
21
+
22
+ ---
23
+
24
+ ## 1. `SodaxWalletProvider` props (largest change)
25
+
26
+ ### What changed
27
+
28
+ v1 spread chain configuration across **three separate props**: `rpcConfig` (per-chain RPC URLs), `options` (per-adapter options like `wagmi.ssr`, `solana.autoConnect`, `sui.autoConnect`), and `initialState` (wagmi state for SSR hydration).
29
+
30
+ v2 collapses all three into a **single `config` prop** of type `SodaxWalletConfig`. The new shape uses **chain-type slots** (`EVM`, `SOLANA`, `SUI`, `BITCOIN`, `STELLAR`, `ICON`, `INJECTIVE`, `NEAR`, `STACKS`) at the top level. Each slot is `ChainTypeConfig<T>` — adapter options merged with `{ chains?, connectors? }` where `chains` is keyed by `ChainKey` and holds per-chain `{ rpcUrl?, defaults? }`.
31
+
32
+ ### Why
33
+
34
+ - **Configurable chain opt-in.** v1 always mounted every chain adapter regardless of need. v2 mounts only the slots you include — omit a slot to skip it entirely. Pass `{}` to mount with SDK defaults.
35
+ - **Single source of truth.** v1 spread chain knowledge across three independent props that had to stay in sync; the new `config` shape derives `enabledChains`, `chains`, and per-chain defaults from one tree.
36
+ - **Per-chain `defaults`.** v2 lets each chain entry hold call-level defaults (e.g. EVM `waitForTransactionReceipt.confirmations`) that flow to the bridged `IXxxWalletProvider`.
37
+
38
+ ### How to migrate
39
+
40
+ See [`reference/config.md`](./reference/config.md) for the mechanical mapping. See [`recipes/`](./recipes/) for paired before/after code in common patterns.
41
+
42
+ ---
43
+
44
+ ## 2. `QueryClientProvider` is no longer mounted internally
45
+
46
+ ### What changed
47
+
48
+ v1 created its own `QueryClient` inside `SodaxWalletProvider` and wrapped children with `<QueryClientProvider>` automatically. v2 expects the consumer to provide one, externally.
49
+
50
+ ### Why
51
+
52
+ - **One QueryClient per app, not per package.** v1's behavior caused subtle bugs when an app already had its own `QueryClient` for app-level queries — there were two clients, two caches, and React Query devtools showed only one.
53
+ - **Predictable provider order.** Consumers can now mount `QueryClientProvider` at the position that fits their app — between auth providers and `SodaxWalletProvider`, around route boundaries, etc.
54
+
55
+ ### How to migrate
56
+
57
+ Wrap `<SodaxWalletProvider>` with `<QueryClientProvider>` at the call site:
58
+
59
+ ```tsx
60
+ // v2 ✅
61
+ <QueryClientProvider client={queryClient}>
62
+ <SodaxWalletProvider config={walletConfig}>{children}</SodaxWalletProvider>
63
+ </QueryClientProvider>
64
+ ```
65
+
66
+ Add `@tanstack/react-query` as a direct dependency if not already present:
67
+
68
+ ```bash
69
+ pnpm add @tanstack/react-query
70
+ ```
71
+
72
+ ---
73
+
74
+ ## 3. Hooks now take an options object, not positional args
75
+
76
+ ### What changed
77
+
78
+ Every public hook that took a `xChainType` or `chainIdentifier` positional argument now takes an options object with named fields. The same applies to the **callback returned by `useXDisconnect`** — `await disconnect('EVM')` is now `await disconnect({ xChainType: 'EVM' })`.
79
+
80
+ ### Why
81
+
82
+ - **Forward compatibility.** Adding new fields (e.g. `xChainId` alongside `xChainType`) without breaking call sites.
83
+ - **Disambiguation.** v1 `useXAccount(chainIdentifier)` accepted both `ChainType` (`'EVM'`) and `ChainId` (`'0x1.eth'`) and detected at runtime. v2 splits them — `xChainType: ChainType` vs `xChainId: SpokeChainKey` — and the type system enforces "exactly one".
84
+
85
+ ### How to migrate
86
+
87
+ See [`reference/hooks.md`](./reference/hooks.md) for the per-hook signature map. The `useXDisconnect` returned-callback case typically surfaces as `TS2345: Argument of type 'string' is not assignable to parameter of type 'UseXDisconnectArgs'`.
88
+
89
+ ---
90
+
91
+ ## 4. Store hook removed from the public API
92
+
93
+ ### What changed
94
+
95
+ v1 exported the Zustand store hook as `useXWagmiStore` from the package barrel. v2 **does not export the store hook at all** — direct store access is no longer part of the public API. The localStorage **persistence key is unchanged** (`xwagmi-store`) so existing user connections survive the upgrade.
96
+
97
+ ### Why
98
+
99
+ - **Public surface should be the hook layer.** Reading store state directly couples consumers to internal field shapes that change between minor versions. v2 provides one public hook per consumer concern (`useXService`, `useXConnection`, `useXConnectors`, …) so internal store renames don't break consumers.
100
+ - **localStorage compatibility.** Renaming the persistence key would log every user out on upgrade. The internal store rename (which v2 also did) keeps the localStorage key intact.
101
+
102
+ ### How to migrate
103
+
104
+ For each `useXWagmiStore(state => state.X)` selector, replace with the equivalent public hook. There is no `useXWalletStore` import to rename to. See [`reference/imports.md`](./reference/imports.md) § "Store hook removed" for the field-to-hook map.
105
+
106
+ ---
107
+
108
+ ## 5. Concrete chain classes moved behind sub-path imports
109
+
110
+ ### What changed
111
+
112
+ v1 re-exported every concrete `XService` and `XConnector` class from the package barrel:
113
+
114
+ ```diff
115
+ - // v1 — barrel exports concrete classes
116
+ - import { EvmXService, XverseXConnector, IconHanaXConnector } from '@sodax/wallet-sdk-react';
117
+ ```
118
+
119
+ v2's barrel exports only **types, hooks, abstractions, and `SodaxWalletProvider`**. Concrete chain classes live behind sub-paths:
120
+
121
+ ```ts
122
+ // v2 — concrete classes via sub-path
123
+ import { XverseXConnector } from '@sodax/wallet-sdk-react/xchains/bitcoin';
124
+ ```
125
+
126
+ ### Why
127
+
128
+ - **API surface hygiene.** Consumers who only use hooks shouldn't pull concrete chain classes into their bundle just because they were re-exported. v2's barrel is shaped around the consumer-facing API; advanced use (e.g. `instanceof`) opts in via deep imports.
129
+ - **Adding chains is non-breaking.** v1 required updating `index.ts` whenever a new chain landed. v2 auto-discovers per-chain entries via tsup glob — adding a chain doesn't touch the barrel.
130
+
131
+ ### How to migrate
132
+
133
+ See [`reference/imports.md`](./reference/imports.md) for the sub-path map per chain.
134
+
135
+ ---
136
+
137
+ ## 6. Chain-type opt-in (mounting behavior)
138
+
139
+ ### What changed
140
+
141
+ v1 mounted **every** chain adapter (wagmi, `@solana/wallet-adapter`, `@mysten/dapp-kit`) and registered services for every chain regardless of whether the consumer used them.
142
+
143
+ v2 mounts only the slots present in `walletConfig`. An app that only needs EVM + Sui passes `{ EVM: {...}, SUI: {...} }` and ships **none** of the Solana / Bitcoin / NEAR adapter code in the React tree.
144
+
145
+ ### Why
146
+
147
+ - **Bundle size.** v1 forced every consumer to ship every adapter. v2 lets you opt in.
148
+ - **Provider context isolation.** Apps that don't need Solana don't get the `WalletProvider` from `@solana/wallet-adapter` in their context — fewer renders, fewer dev-tool nodes.
149
+
150
+ ### How to migrate
151
+
152
+ Add only the chain-type slots your app actually uses to `walletConfig`. See [`reference/config.md`](./reference/config.md). New behavior: `useXConnectors({ xChainType: 'X' })` returns `[]` for chains not in `enabledChains` and logs a one-time warning.
153
+
154
+ ---
155
+
156
+ ## 7. EVM = single connection across every configured EVM network
157
+
158
+ ### What changed
159
+
160
+ v1 had one connector per chain in some flows (legacy from earlier wagmi versions). v2 treats EVM as **one logical connection** that spans every configured EVM chain — there is no per-network connect/disconnect, and `useChainGroups` collapses EVM into a single row.
161
+
162
+ ### Why
163
+
164
+ - **Match wagmi's actual semantics.** wagmi has always modeled EVM connection as one connector per session that hops between configured chains via `wagmi.switchChain`. v1's per-chain UI was a workaround.
165
+ - **Multi-chain dApps.** Users connect once and operate across every EVM network the app supports — no re-authorization on each chain switch.
166
+
167
+ ### How to migrate
168
+
169
+ Audit any UI that exposed per-EVM-chain connect/disconnect. Replace with a single "EVM" entry. Use `useEvmSwitchChain` for switching. See [`recipes/connect-button.md`](./recipes/connect-button.md) and [`recipes/multi-chain-modal.md`](./recipes/multi-chain-modal.md).
170
+
171
+ ---
172
+
173
+ ## 8. New: WalletConnect support for EVM
174
+
175
+ ### What changed
176
+
177
+ v2 adds `EVM.walletConnect.projectId` to `walletConfig` to enable the WalletConnect connector. v1 did not support WalletConnect — only EIP-6963 injected wallets.
178
+
179
+ ### Why
180
+
181
+ - **Enterprise custody.** Partners using Fireblocks / Ledger Live / mobile-only wallets cannot install browser extensions. WalletConnect is the only viable protocol.
182
+ - **Backwards compatible default.** Omitting `walletConnect` from the config preserves v1 behavior (EIP-6963 only).
183
+
184
+ ### How to migrate
185
+
186
+ Not breaking — additive. See [`recipes/walletconnect-migration.md`](./recipes/walletconnect-migration.md) for opt-in.
187
+
188
+ ---
189
+
190
+ ## 9. New: headless wallet modal primitives
191
+
192
+ ### What changed
193
+
194
+ v2 ships `useWalletModal`, `useChainGroups`, `useConnectedChains`, `useBatchConnect`, `useBatchDisconnect`, `useIsWalletInstalled`, `useConnectionFlow`. None of these existed in v1.
195
+
196
+ ### Why
197
+
198
+ - **Bring-your-own UI.** v1 left the modal UX to the consumer. v2 ships state-machine primitives — render-agnostic — so apps can build modal UX without rebuilding the chain registry / connector dispatch logic from scratch.
199
+
200
+ ### How to migrate
201
+
202
+ Not breaking — additive. See [`recipes/multi-chain-modal.md`](./recipes/multi-chain-modal.md) for the modern pattern.
203
+
204
+ ---
205
+
206
+ ## 10. Removed: `useXBalances`
207
+
208
+ ### What changed
209
+
210
+ v1 exported `useXBalances({ xChainId, xTokens, address })` from `@sodax/wallet-sdk-react`. v2 removes it. A hook with the same name lives in `@sodax/dapp-kit`, but the **signature has changed**:
211
+
212
+ ```diff
213
+ - // v1 ❌ — from wallet-sdk-react
214
+ - import { useXBalances } from '@sodax/wallet-sdk-react';
215
+ - const { data } = useXBalances({ xChainId, xTokens, address });
216
+ + // v2 ✅ — from dapp-kit, params are now wrapped
217
+ + import { useXBalances } from '@sodax/dapp-kit';
218
+ + import { useXService } from '@sodax/wallet-sdk-react';
219
+ + const xService = useXService({ xChainType: 'EVM' });
220
+ + const { data } = useXBalances({ params: { xService, xChainId, xTokens, address } });
221
+ ```
222
+
223
+ ### Why
224
+
225
+ - **Wrong package.** Token-balance queries are a dApp-feature concern, not a wallet-sdk concern. The hook required token metadata, RPC routing, and refetch policies — none of which belong in a wallet SDK.
226
+ - **`xService` is now an explicit input.** v2 surfaces the chain service to the call site so query keys are stable across config changes and the hook is testable in isolation.
227
+
228
+ ### How to migrate
229
+
230
+ 1. `pnpm add @sodax/dapp-kit` if not already installed.
231
+ 2. Switch the import path: `'@sodax/wallet-sdk-react'` → `'@sodax/dapp-kit'`.
232
+ 3. Wrap the existing arg as `{ params: { xService, xChainId, xTokens, address } }` and pass `xService` from `useXService({ xChainType })`.
233
+
234
+ If you cannot add dapp-kit, port the call to direct `viem` / `@solana/web3.js` reads with your own `useQuery`.
235
+
236
+ ---
237
+
238
+ ## 11. `useEvmSwitchChain` reshaped
239
+
240
+ ### What changed
241
+
242
+ v1 forwarded wagmi's `switchChain` mutation directly:
243
+
244
+ ```ts
245
+ // v1 ❌
246
+ const { switchChain } = useEvmSwitchChain();
247
+ await switchChain({ chainId: 1 });
248
+ ```
249
+
250
+ v2 takes a target `xChainId` and exposes wrong-network state:
251
+
252
+ ```ts
253
+ // v2 ✅
254
+ import { ChainKeys } from '@sodax/types';
255
+
256
+ const { isWrongChain, handleSwitchChain } = useEvmSwitchChain({
257
+ xChainId: ChainKeys.ETHEREUM_MAINNET,
258
+ });
259
+ ```
260
+
261
+ ### Why
262
+
263
+ - **Single source of truth for "expected chain".** UI code repeatedly recomputed `connectedChainId !== expectedChainId`. The hook owns that comparison once.
264
+ - **Injective + MetaMask.** v2 transparently handles the Injective-via-MetaMask case (auto-switches to Ethereum mainnet). v1 callers had to bolt this on.
265
+ - **Safe when EVM is disabled.** If the consumer's `walletConfig` omits the `EVM` slot, v2 returns no-op values instead of throwing.
266
+
267
+ ### How to migrate
268
+
269
+ Replace the destructured `switchChain` with `handleSwitchChain` and feed the target chain via `xChainId`. Render the network-mismatch CTA from `isWrongChain`. See [`reference/hooks.md`](./reference/hooks.md) for examples.
270
+
271
+ ---
272
+
273
+ ## 12. `SodaxWalletProvider` freezes config on first render
274
+
275
+ ### What changed
276
+
277
+ v1 re-derived chain config on every render whose `rpcConfig` / `options` reference changed. v2 **captures `config` once on mount** and ignores subsequent prop changes. To swap config at runtime, remount with a new `key`.
278
+
279
+ ### Why
280
+
281
+ - **Stable wagmi config object.** wagmi's `WagmiProvider` is sensitive to config-object identity changes — re-creating the config triggers re-connection and breaks in-flight transactions.
282
+ - **Predictable identity.** Apps should compose chain config once at startup, not derive it dynamically. Hot config swaps were rare in v1 but caused hard-to-debug reconnect storms.
283
+
284
+ ### How to migrate
285
+
286
+ If you previously updated `rpcConfig` reactively, route the change through a remount:
287
+
288
+ ```tsx
289
+ <SodaxWalletProvider key={configVersion} config={walletConfig}>
290
+ {children}
291
+ </SodaxWalletProvider>
292
+ ```
293
+
294
+ Bumping `configVersion` (e.g. when the user picks a new RPC endpoint) forces a clean re-init of all chain services.
295
+
296
+ ---
297
+
298
+ ## What did NOT change
299
+
300
+ - Chain support: still 9 chain types (EVM, BITCOIN, INJECTIVE, STELLAR, SUI, SOLANA, ICON, NEAR, STACKS).
301
+ - Persisted localStorage key: still `xwagmi-store`.
302
+ - Devtools store name: still `xwagmi-store`.
303
+ - Peer dependencies: `react >= 19`, `@tanstack/react-query 5.x`.
304
+ - `XService` / `XConnector` abstract base contract (still has `connect()` / `disconnect()` / `getXConnectors()`).
305
+ - Public `XAccount`, `XConnection`, `WalletId` types in `@sodax/types`.
@@ -0,0 +1,159 @@
1
+ # Migration Checklist (Machine-Checkable)
2
+
3
+ Run these checks after every code change and at the end of the migration. Each item has a concrete `grep` / typecheck command. Loop through until all are checked.
4
+
5
+ ---
6
+
7
+ ## Provider migration
8
+
9
+ - [ ] `SodaxWalletProvider` is mounted exactly once in app source.
10
+ ```bash
11
+ grep -rn "SodaxWalletProvider" <user-src> --include="*.tsx" --include="*.ts" | grep -v "import" | wc -l
12
+ # expect 1 (the JSX usage)
13
+ ```
14
+
15
+ - [ ] `SodaxWalletProvider` uses the v2 `config` prop (no `rpcConfig` / `options` / `initialState`).
16
+ ```bash
17
+ grep -rnE "SodaxWalletProvider[^/>]*\b(rpcConfig|initialState|options)\s*=" <user-src>
18
+ # expect empty
19
+ ```
20
+
21
+ - [ ] `QueryClientProvider` wraps `SodaxWalletProvider`.
22
+ ```bash
23
+ # Manual — open the provider file and confirm:
24
+ # <QueryClientProvider client={queryClient}>
25
+ # <SodaxWalletProvider config={walletConfig}>
26
+ ```
27
+
28
+ - [ ] If app is Next.js, `EVM.ssr: true` is set in `walletConfig`.
29
+ ```bash
30
+ grep -rnE "EVM:\s*\{[^}]*\bssr:\s*true" <user-src>
31
+ # expect at least one match if Next.js
32
+ ```
33
+
34
+ ---
35
+
36
+ ## Store migration
37
+
38
+ - [ ] No `useXWagmiStore` imports remain (the v2 barrel removed the store hook entirely — every call site must be replaced with a public hook).
39
+ ```bash
40
+ grep -rn "useXWagmiStore" <user-src>
41
+ # expect empty
42
+ ```
43
+
44
+ - [ ] No `useXWalletStore` imports were introduced (v2 does not export the store hook under either name).
45
+ ```bash
46
+ grep -rn "useXWalletStore" <user-src>
47
+ # expect empty
48
+ ```
49
+
50
+ - [ ] Every former store read uses a public hook (`useXService` / `useXServices` / `useXConnection` / `useXConnections` / `useEnabledChains` / `useWalletProvider`). See [`reference/imports.md`](./reference/imports.md) § "Store hook removed" for the field-to-hook map.
51
+
52
+ ---
53
+
54
+ ## Hook signature migration
55
+
56
+ - [ ] No positional hook calls remain.
57
+ ```bash
58
+ # All of these must be empty:
59
+ grep -rnE "useXAccount\(['\"]" <user-src>
60
+ grep -rnE "useXConnectors\(['\"]" <user-src>
61
+ grep -rnE "useXConnection\(['\"]" <user-src>
62
+ grep -rnE "useXService\(['\"]" <user-src>
63
+ grep -rnE "useWalletProvider\(['\"]" <user-src>
64
+ ```
65
+
66
+ - [ ] All call sites pass `{ xChainType }` or `{ xChainId }`, never both.
67
+ ```bash
68
+ grep -rnE "useXAccount\(\{[^}]*xChainType[^}]*xChainId" <user-src>
69
+ grep -rnE "useXAccount\(\{[^}]*xChainId[^}]*xChainType" <user-src>
70
+ # expect empty
71
+ ```
72
+
73
+ - [ ] No `useXDisconnect` callback called with positional ChainType (v2 takes `{ xChainType }` object).
74
+ ```bash
75
+ # The hook itself is identical in v1/v2; the BREAKING change is on the returned callback.
76
+ # Look for callbacks invoked with a bare string instead of an options object.
77
+ grep -rnE "disconnect\((['\"](EVM|SOLANA|SUI|BITCOIN|STELLAR|ICON|INJECTIVE|NEAR|STACKS)['\"])\)" <user-src>
78
+ # expect empty — replace with `disconnect({ xChainType: 'EVM' })`
79
+ ```
80
+
81
+ - [ ] No `useEvmSwitchChain` destructuring of `switchChain` (v2 returns `{ isWrongChain, handleSwitchChain }`).
82
+ ```bash
83
+ grep -rnE "useEvmSwitchChain\(\)" <user-src>
84
+ # expect empty — v2 requires `{ xChainId }`
85
+ grep -rnE "const \{[^}]*\bswitchChain\b[^}]*\} = useEvmSwitchChain" <user-src>
86
+ # expect empty — switchChain is no longer destructurable from this hook
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Sub-path imports
92
+
93
+ - [ ] No concrete chain classes are imported from the package barrel.
94
+ ```bash
95
+ grep -rnE "from '@sodax/wallet-sdk-react'" <user-src> | grep -E "EvmXService|SolanaXService|SuiXService|BitcoinXService|StellarXService|InjectiveXService|IconXService|NearXService|StacksXService|EvmXConnector|SolanaXConnector|SuiXConnector|UnisatXConnector|XverseXConnector|OKXXConnector|StellarWalletsKitXConnector|InjectiveXConnector|IconHanaXConnector|NearXConnector|StacksXConnector"
96
+ # expect empty (or only `import type` lines, which are still allowed for some types)
97
+ ```
98
+
99
+ - [ ] Concrete classes use sub-path imports (`@sodax/wallet-sdk-react/xchains/<chain>`).
100
+ ```bash
101
+ grep -rnE "from '@sodax/wallet-sdk-react/xchains/" <user-src>
102
+ # if user code needs concrete classes, expect matches here
103
+ ```
104
+
105
+ ---
106
+
107
+ ## Removed APIs
108
+
109
+ - [ ] No `useXBalances` calls remain that import from `@sodax/wallet-sdk-react` (moved to `@sodax/dapp-kit` with a new signature).
110
+ ```bash
111
+ grep -rn "from '@sodax/wallet-sdk-react'" <user-src> | grep useXBalances
112
+ # expect empty — v2 imports from '@sodax/dapp-kit', wraps args as `{ params: { xService, xChainId, xTokens, address } }`
113
+ ```
114
+
115
+ - [ ] No `useEthereumChainId` imports remain (internal in v2).
116
+ ```bash
117
+ grep -rn "useEthereumChainId" <user-src>
118
+ # expect empty — replace with wagmi's `useAccount().chainId` or `useEvmSwitchChain({ xChainId })`
119
+ ```
120
+
121
+ ---
122
+
123
+ ## Behavior verification
124
+
125
+ - [ ] `pnpm checkTs` exits clean (in the user's app root).
126
+ ```bash
127
+ pnpm checkTs
128
+ # expect exit code 0
129
+ ```
130
+
131
+ - [ ] Connect/disconnect flow works in dev environment (manual).
132
+ ```
133
+ # Manual:
134
+ # 1. pnpm dev
135
+ # 2. Click connect on each enabled chain
136
+ # 3. Confirm address renders, localStorage has `xwagmi-store` key with the new connection
137
+ # 4. Reload — confirm connection survives
138
+ # 5. Click disconnect — confirm `xwagmi-store` clears that chain
139
+ ```
140
+
141
+ - [ ] EVM treated as single connection (manual; only if app had per-EVM-chain UI in v1).
142
+ ```
143
+ # Manual:
144
+ # 1. Connect to EVM with any wallet
145
+ # 2. Confirm useChainGroups returns one EVM row, not per-network rows
146
+ # 3. Confirm useEvmSwitchChain switches the active network without re-connecting
147
+ ```
148
+
149
+ ---
150
+
151
+ ## Done criteria
152
+
153
+ The migration is complete when:
154
+
155
+ - [ ] All sections above are checked.
156
+ - [ ] User has confirmed the app's connect / disconnect / sign flows work end-to-end.
157
+ - [ ] Tests are updated (if any test mocks `XService` / `useXWagmiStore`) — flagged in stop conditions; defer to user.
158
+
159
+ If any item fails or is ambiguous, **stop and ask the user**. Do not declare complete until every box is ticked.