@sodax/skills 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 (202) hide show
  1. package/.claude-plugin/plugin.json +18 -0
  2. package/AGENTS.md +83 -0
  3. package/LICENSE +21 -0
  4. package/README.md +49 -0
  5. package/package.json +58 -0
  6. package/skills/sodax-dapp-kit/SKILL.md +129 -0
  7. package/skills/sodax-dapp-kit/integration/knowledge/README.md +49 -0
  8. package/skills/sodax-dapp-kit/integration/knowledge/ai-rules.md +80 -0
  9. package/skills/sodax-dapp-kit/integration/knowledge/architecture.md +276 -0
  10. package/skills/sodax-dapp-kit/integration/knowledge/features/README.md +29 -0
  11. package/skills/sodax-dapp-kit/integration/knowledge/features/auxiliary-services.md +169 -0
  12. package/skills/sodax-dapp-kit/integration/knowledge/features/bitcoin.md +87 -0
  13. package/skills/sodax-dapp-kit/integration/knowledge/features/bridge.md +91 -0
  14. package/skills/sodax-dapp-kit/integration/knowledge/features/dex.md +152 -0
  15. package/skills/sodax-dapp-kit/integration/knowledge/features/migration.md +118 -0
  16. package/skills/sodax-dapp-kit/integration/knowledge/features/money-market.md +144 -0
  17. package/skills/sodax-dapp-kit/integration/knowledge/features/staking.md +123 -0
  18. package/skills/sodax-dapp-kit/integration/knowledge/features/swap.md +101 -0
  19. package/skills/sodax-dapp-kit/integration/knowledge/quickstart.md +188 -0
  20. package/skills/sodax-dapp-kit/integration/knowledge/recipes/README.md +136 -0
  21. package/skills/sodax-dapp-kit/integration/knowledge/recipes/backend-queries.md +157 -0
  22. package/skills/sodax-dapp-kit/integration/knowledge/recipes/bitcoin.md +193 -0
  23. package/skills/sodax-dapp-kit/integration/knowledge/recipes/bridge.md +174 -0
  24. package/skills/sodax-dapp-kit/integration/knowledge/recipes/dex.md +204 -0
  25. package/skills/sodax-dapp-kit/integration/knowledge/recipes/invalidations.md +115 -0
  26. package/skills/sodax-dapp-kit/integration/knowledge/recipes/migration.md +212 -0
  27. package/skills/sodax-dapp-kit/integration/knowledge/recipes/money-market.md +207 -0
  28. package/skills/sodax-dapp-kit/integration/knowledge/recipes/mutation-error-handling.md +118 -0
  29. package/skills/sodax-dapp-kit/integration/knowledge/recipes/observability.md +93 -0
  30. package/skills/sodax-dapp-kit/integration/knowledge/recipes/setup.md +168 -0
  31. package/skills/sodax-dapp-kit/integration/knowledge/recipes/staking.md +202 -0
  32. package/skills/sodax-dapp-kit/integration/knowledge/recipes/swap.md +272 -0
  33. package/skills/sodax-dapp-kit/integration/knowledge/recipes/wallet-connectivity.md +128 -0
  34. package/skills/sodax-dapp-kit/integration/knowledge/reference/README.md +12 -0
  35. package/skills/sodax-dapp-kit/integration/knowledge/reference/glossary.md +190 -0
  36. package/skills/sodax-dapp-kit/integration/knowledge/reference/hooks-index.md +190 -0
  37. package/skills/sodax-dapp-kit/integration/knowledge/reference/public-api.md +110 -0
  38. package/skills/sodax-dapp-kit/integration/knowledge/reference/querykey-conventions.md +179 -0
  39. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/README.md +60 -0
  40. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/ai-rules.md +81 -0
  41. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/breaking-changes/hook-signatures.md +233 -0
  42. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/breaking-changes/querykey-conventions.md +108 -0
  43. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/breaking-changes/result-handling.md +211 -0
  44. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/breaking-changes/sdk-leakage.md +167 -0
  45. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/checklist.md +89 -0
  46. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/features/README.md +34 -0
  47. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/features/auxiliary-services.md +114 -0
  48. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/features/bitcoin.md +88 -0
  49. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/features/bridge.md +160 -0
  50. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/features/dex.md +101 -0
  51. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/features/migration.md +120 -0
  52. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/features/money-market.md +139 -0
  53. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/features/staking.md +109 -0
  54. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/features/swap.md +133 -0
  55. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/recipes.md +185 -0
  56. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/reference/README.md +15 -0
  57. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/reference/deleted-hooks.md +110 -0
  58. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/reference/error-shape-crosswalk.md +144 -0
  59. package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/reference/renamed-hooks.md +68 -0
  60. package/skills/sodax-sdk/SKILL.md +140 -0
  61. package/skills/sodax-sdk/backend-api/SKILL.md +52 -0
  62. package/skills/sodax-sdk/bridge/SKILL.md +49 -0
  63. package/skills/sodax-sdk/dex/SKILL.md +50 -0
  64. package/skills/sodax-sdk/integration/knowledge/README.md +43 -0
  65. package/skills/sodax-sdk/integration/knowledge/ai-rules.md +75 -0
  66. package/skills/sodax-sdk/integration/knowledge/architecture.md +517 -0
  67. package/skills/sodax-sdk/integration/knowledge/chain-specifics.md +189 -0
  68. package/skills/sodax-sdk/integration/knowledge/features/README.md +21 -0
  69. package/skills/sodax-sdk/integration/knowledge/features/backend-api.md +81 -0
  70. package/skills/sodax-sdk/integration/knowledge/features/bridge.md +172 -0
  71. package/skills/sodax-sdk/integration/knowledge/features/dex.md +182 -0
  72. package/skills/sodax-sdk/integration/knowledge/features/migration.md +181 -0
  73. package/skills/sodax-sdk/integration/knowledge/features/money-market.md +198 -0
  74. package/skills/sodax-sdk/integration/knowledge/features/partner.md +63 -0
  75. package/skills/sodax-sdk/integration/knowledge/features/recovery.md +50 -0
  76. package/skills/sodax-sdk/integration/knowledge/features/staking.md +171 -0
  77. package/skills/sodax-sdk/integration/knowledge/features/swap.md +273 -0
  78. package/skills/sodax-sdk/integration/knowledge/quickstart.md +213 -0
  79. package/skills/sodax-sdk/integration/knowledge/recipes/README.md +21 -0
  80. package/skills/sodax-sdk/integration/knowledge/recipes/backend-server-init.md +69 -0
  81. package/skills/sodax-sdk/integration/knowledge/recipes/chain-key-narrowing.md +65 -0
  82. package/skills/sodax-sdk/integration/knowledge/recipes/gas-estimation.md +33 -0
  83. package/skills/sodax-sdk/integration/knowledge/recipes/initialize-sodax.md +78 -0
  84. package/skills/sodax-sdk/integration/knowledge/recipes/raw-tx-flow.md +71 -0
  85. package/skills/sodax-sdk/integration/knowledge/recipes/result-and-errors.md +104 -0
  86. package/skills/sodax-sdk/integration/knowledge/recipes/signed-tx-flow.md +46 -0
  87. package/skills/sodax-sdk/integration/knowledge/recipes/testing.md +101 -0
  88. package/skills/sodax-sdk/integration/knowledge/reference/README.md +18 -0
  89. package/skills/sodax-sdk/integration/knowledge/reference/chain-keys.md +67 -0
  90. package/skills/sodax-sdk/integration/knowledge/reference/error-codes.md +165 -0
  91. package/skills/sodax-sdk/integration/knowledge/reference/glossary.md +32 -0
  92. package/skills/sodax-sdk/integration/knowledge/reference/public-api.md +138 -0
  93. package/skills/sodax-sdk/integration/knowledge/reference/wallet-providers.md +62 -0
  94. package/skills/sodax-sdk/migration/SKILL.md +65 -0
  95. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/README.md +58 -0
  96. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/ai-rules.md +76 -0
  97. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/breaking-changes/architecture.md +344 -0
  98. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/breaking-changes/result-and-errors.md +363 -0
  99. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/breaking-changes/type-system.md +341 -0
  100. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/checklist.md +67 -0
  101. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/README.md +37 -0
  102. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/backend-api.md +92 -0
  103. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/bridge.md +128 -0
  104. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/dex.md +143 -0
  105. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/migration.md +151 -0
  106. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/money-market.md +214 -0
  107. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/partner.md +59 -0
  108. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/recovery.md +35 -0
  109. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/staking.md +143 -0
  110. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/swap.md +198 -0
  111. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/recipes.md +350 -0
  112. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/reference/README.md +18 -0
  113. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/reference/deleted-exports.md +127 -0
  114. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/reference/error-code-crosswalk.md +104 -0
  115. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/reference/return-shapes.md +49 -0
  116. package/skills/sodax-sdk/migration-v1-to-v2/knowledge/reference/sodax-config.md +145 -0
  117. package/skills/sodax-sdk/money-market/SKILL.md +52 -0
  118. package/skills/sodax-sdk/partner/SKILL.md +51 -0
  119. package/skills/sodax-sdk/recovery/SKILL.md +49 -0
  120. package/skills/sodax-sdk/staking/SKILL.md +49 -0
  121. package/skills/sodax-sdk/swap/SKILL.md +67 -0
  122. package/skills/sodax-wallet-sdk-core/SKILL.md +114 -0
  123. package/skills/sodax-wallet-sdk-core/integration/knowledge/README.md +108 -0
  124. package/skills/sodax-wallet-sdk-core/integration/knowledge/ai-rules.md +141 -0
  125. package/skills/sodax-wallet-sdk-core/integration/knowledge/architecture.md +212 -0
  126. package/skills/sodax-wallet-sdk-core/integration/knowledge/features/README.md +22 -0
  127. package/skills/sodax-wallet-sdk-core/integration/knowledge/features/bitcoin.md +103 -0
  128. package/skills/sodax-wallet-sdk-core/integration/knowledge/features/evm.md +102 -0
  129. package/skills/sodax-wallet-sdk-core/integration/knowledge/features/icon.md +88 -0
  130. package/skills/sodax-wallet-sdk-core/integration/knowledge/features/injective.md +92 -0
  131. package/skills/sodax-wallet-sdk-core/integration/knowledge/features/near.md +92 -0
  132. package/skills/sodax-wallet-sdk-core/integration/knowledge/features/solana.md +104 -0
  133. package/skills/sodax-wallet-sdk-core/integration/knowledge/features/stacks.md +91 -0
  134. package/skills/sodax-wallet-sdk-core/integration/knowledge/features/stellar.md +95 -0
  135. package/skills/sodax-wallet-sdk-core/integration/knowledge/features/sui.md +96 -0
  136. package/skills/sodax-wallet-sdk-core/integration/knowledge/quickstart.md +259 -0
  137. package/skills/sodax-wallet-sdk-core/integration/knowledge/recipes/README.md +15 -0
  138. package/skills/sodax-wallet-sdk-core/integration/knowledge/recipes/bridge-to-sdk.md +145 -0
  139. package/skills/sodax-wallet-sdk-core/integration/knowledge/recipes/defaults-and-overrides.md +159 -0
  140. package/skills/sodax-wallet-sdk-core/integration/knowledge/recipes/library-exports.md +129 -0
  141. package/skills/sodax-wallet-sdk-core/integration/knowledge/recipes/setup-browser-extension.md +137 -0
  142. package/skills/sodax-wallet-sdk-core/integration/knowledge/recipes/setup-private-key.md +115 -0
  143. package/skills/sodax-wallet-sdk-core/integration/knowledge/recipes/sign-and-broadcast.md +201 -0
  144. package/skills/sodax-wallet-sdk-core/integration/knowledge/recipes/testing.md +163 -0
  145. package/skills/sodax-wallet-sdk-core/integration/knowledge/reference/README.md +13 -0
  146. package/skills/sodax-wallet-sdk-core/integration/knowledge/reference/chain-support.md +65 -0
  147. package/skills/sodax-wallet-sdk-core/integration/knowledge/reference/glossary.md +28 -0
  148. package/skills/sodax-wallet-sdk-core/integration/knowledge/reference/interfaces.md +131 -0
  149. package/skills/sodax-wallet-sdk-core/integration/knowledge/reference/provider-classes.md +54 -0
  150. package/skills/sodax-wallet-sdk-core/integration/knowledge/reference/public-api.md +128 -0
  151. package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/README.md +84 -0
  152. package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/ai-rules.md +139 -0
  153. package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/breaking-changes/README.md +14 -0
  154. package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/breaking-changes/base-wallet-provider.md +52 -0
  155. package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/breaking-changes/defaults-config.md +57 -0
  156. package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/breaking-changes/folder-layout.md +99 -0
  157. package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/breaking-changes/library-exports.md +58 -0
  158. package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/checklist.md +62 -0
  159. package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/recipes/README.md +12 -0
  160. package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/recipes/adopt-defaults.md +84 -0
  161. package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/recipes/adopt-library-exports.md +99 -0
  162. package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/reference/README.md +12 -0
  163. package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/reference/added-fields.md +71 -0
  164. package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/reference/deleted-exports.md +35 -0
  165. package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/reference/renamed-symbols.md +31 -0
  166. package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/reference/return-shapes.md +23 -0
  167. package/skills/sodax-wallet-sdk-react/SKILL.md +154 -0
  168. package/skills/sodax-wallet-sdk-react/integration/knowledge/README.md +103 -0
  169. package/skills/sodax-wallet-sdk-react/integration/knowledge/ai-rules.md +136 -0
  170. package/skills/sodax-wallet-sdk-react/integration/knowledge/architecture.md +185 -0
  171. package/skills/sodax-wallet-sdk-react/integration/knowledge/examples/01-minimal-evm.tsx +75 -0
  172. package/skills/sodax-wallet-sdk-react/integration/knowledge/examples/02-multi-chain-modal.tsx +169 -0
  173. package/skills/sodax-wallet-sdk-react/integration/knowledge/examples/03-nextjs-app-router.tsx +99 -0
  174. package/skills/sodax-wallet-sdk-react/integration/knowledge/examples/04-walletconnect-setup.tsx +89 -0
  175. package/skills/sodax-wallet-sdk-react/integration/knowledge/examples/README.md +29 -0
  176. package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/batch-operations.md +224 -0
  177. package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/bridge-to-sdk.md +165 -0
  178. package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/chain-detection.md +259 -0
  179. package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/connect-button.md +159 -0
  180. package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/multi-chain-modal.md +203 -0
  181. package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/setup.md +163 -0
  182. package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/sign-message.md +138 -0
  183. package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/sub-path-imports.md +97 -0
  184. package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/switch-chain.md +144 -0
  185. package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/walletconnect-setup.md +139 -0
  186. package/skills/sodax-wallet-sdk-react/integration/knowledge/reference/api-surface.md +176 -0
  187. package/skills/sodax-wallet-sdk-react/integration/knowledge/reference/chain-support.md +79 -0
  188. package/skills/sodax-wallet-sdk-react/integration/knowledge/reference/connectors.md +75 -0
  189. package/skills/sodax-wallet-sdk-react/integration/knowledge/reference/hooks.md +212 -0
  190. package/skills/sodax-wallet-sdk-react/integration/knowledge/reference/wallet-brands.md +107 -0
  191. package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/README.md +49 -0
  192. package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/ai-rules.md +144 -0
  193. package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/breaking-changes.md +310 -0
  194. package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/checklist.md +159 -0
  195. package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/recipes/connect-button.md +170 -0
  196. package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/recipes/multi-chain-modal.md +245 -0
  197. package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/recipes/ssr-setup.md +165 -0
  198. package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/recipes/walletconnect-migration.md +170 -0
  199. package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/reference/components.md +75 -0
  200. package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/reference/config.md +339 -0
  201. package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/reference/hooks.md +336 -0
  202. package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/reference/imports.md +158 -0
@@ -0,0 +1,170 @@
1
+ # Recipe: Migrate a Single-Chain Connect Button
2
+
3
+ Migrates the most common pattern: one button per chain that lists connectors, lets the user pick one, and shows the connected address. Self-contained — apply this recipe without reading other files.
4
+
5
+ ---
6
+
7
+ ## When to use this recipe
8
+
9
+ Apply when the user's v1 code uses any of:
10
+
11
+ - `useXConnectors('<chain>')` (positional)
12
+ - `useXAccount('<chain>')` (positional)
13
+ - `useXConnect()` + `useXDisconnect()` for a per-chain button
14
+
15
+ If the user has a multi-chain modal (chain picker → connector picker), use [`multi-chain-modal.md`](./multi-chain-modal.md) instead.
16
+
17
+ ---
18
+
19
+ ## Before (v1)
20
+
21
+ ```tsx
22
+ // @ai-snippets-skip
23
+ 'use client';
24
+
25
+ import {
26
+ useXConnectors,
27
+ useXConnect,
28
+ useXAccount,
29
+ useXDisconnect,
30
+ } from '@sodax/wallet-sdk-react';
31
+
32
+ export function EvmConnectButton() {
33
+ const connectors = useXConnectors('EVM');
34
+ const { mutateAsync: connect, isPending } = useXConnect();
35
+ const { address } = useXAccount('EVM');
36
+ const disconnect = useXDisconnect();
37
+
38
+ if (address) {
39
+ return (
40
+ <div>
41
+ Connected: {address}
42
+ <button onClick={() => disconnect('EVM')}>Disconnect</button>
43
+ </div>
44
+ );
45
+ }
46
+
47
+ return (
48
+ <div>
49
+ {connectors.map((connector) => (
50
+ <button
51
+ key={connector.id}
52
+ disabled={isPending}
53
+ onClick={() => connect(connector)}
54
+ >
55
+ Connect with {connector.name}
56
+ </button>
57
+ ))}
58
+ </div>
59
+ );
60
+ }
61
+ ```
62
+
63
+ ---
64
+
65
+ ## After (v2)
66
+
67
+ ```tsx
68
+ 'use client';
69
+
70
+ import {
71
+ useXConnectors,
72
+ useXConnect,
73
+ useXAccount,
74
+ useXDisconnect,
75
+ } from '@sodax/wallet-sdk-react';
76
+
77
+ export function EvmConnectButton() {
78
+ const connectors = useXConnectors({ xChainType: 'EVM' });
79
+ const { mutateAsync: connect, isPending } = useXConnect();
80
+ const { address } = useXAccount({ xChainType: 'EVM' });
81
+ const disconnect = useXDisconnect();
82
+
83
+ if (address) {
84
+ return (
85
+ <div>
86
+ Connected: {address}
87
+ <button onClick={() => disconnect({ xChainType: 'EVM' })}>Disconnect</button>
88
+ </div>
89
+ );
90
+ }
91
+
92
+ return (
93
+ <div>
94
+ {connectors.map((connector) => (
95
+ <button
96
+ key={connector.id}
97
+ disabled={isPending}
98
+ onClick={() => connect(connector)}
99
+ >
100
+ Connect with {connector.name}
101
+ </button>
102
+ ))}
103
+ </div>
104
+ );
105
+ }
106
+ ```
107
+
108
+ ---
109
+
110
+ ## What changed
111
+
112
+ | Line | v1 | v2 |
113
+ |---|---|---|
114
+ | `useXConnectors` | `useXConnectors('EVM')` | `useXConnectors({ xChainType: 'EVM' })` |
115
+ | `useXAccount` | `useXAccount('EVM')` | `useXAccount({ xChainType: 'EVM' })` |
116
+ | `useXConnect` mutation arg | pass `connector` to `mutateAsync` | unchanged |
117
+ | `useXDisconnect` returned callback | `disconnect('EVM')` | `disconnect({ xChainType: 'EVM' })` |
118
+
119
+ The mechanical changes are the **three hook usages** above. The `useXDisconnect` callback shape changed in v2 — see [`../reference/hooks.md`](../reference/hooks.md) § `useXDisconnect`.
120
+
121
+ ---
122
+
123
+ ## Variations
124
+
125
+ ### Per-chain-id (e.g. one connect button per EVM network)
126
+
127
+ If v1 used `useXAccount('0x1.eth')`:
128
+
129
+ ```tsx
130
+ // @ai-snippets-skip
131
+ // v1 ❌
132
+ const { address } = useXAccount('0x1.eth');
133
+ ```
134
+
135
+ Use the typed chain key in v2:
136
+
137
+ ```tsx
138
+ // @ai-snippets-skip
139
+ // v2 ✅
140
+ import { ChainKeys } from '@sodax/types';
141
+ const { address } = useXAccount({ xChainId: ChainKeys.ETHEREUM_MAINNET });
142
+ ```
143
+
144
+ > ⚠️ If the v1 button is "connect to Ethereum", remember v2 treats EVM as a **single connection across every configured EVM network**. A per-Ethereum button is rarely what users want — consider replacing with a single "EVM" button + `useEvmSwitchChain` for network switching. See [`../breaking-changes.md`](../breaking-changes.md) §7.
145
+
146
+ ### Sui / Solana / etc.
147
+
148
+ Replace `'EVM'` with the chain type the button targets — the migration is mechanical:
149
+
150
+ ```tsx
151
+ // @ai-snippets-skip
152
+ const connectors = useXConnectors({ xChainType: 'SUI' });
153
+ const { address } = useXAccount({ xChainType: 'SUI' });
154
+ ```
155
+
156
+ ---
157
+
158
+ ## Verification
159
+
160
+ ```bash
161
+ # 1. Type check
162
+ pnpm checkTs
163
+
164
+ # 2. Confirm no positional hook args remain in this file
165
+ grep -nE "useXAccount\(['\"]" <file>
166
+ grep -nE "useXConnectors\(['\"]" <file>
167
+ # expect empty
168
+
169
+ # 3. Manual — load page, click connect, confirm address renders
170
+ ```
@@ -0,0 +1,245 @@
1
+ # Recipe: Migrate a Multi-Chain Wallet Modal
2
+
3
+ Replaces a hand-rolled v1 modal (chain picker → connector picker → connect) with v2's headless `useWalletModal` state machine. Self-contained — apply this recipe without reading other files.
4
+
5
+ ---
6
+
7
+ ## When to use this recipe
8
+
9
+ Apply when the user's v1 code:
10
+
11
+ - Maintains its own state for "which chain is the user picking"
12
+ - Calls `useXConnectors(<chain>)` per chain in a loop
13
+ - Calls `useXConnect` directly from a click handler
14
+ - Tracks a `connecting` / `success` / `error` state by hand
15
+
16
+ v2 ships these primitives so the consumer focuses only on UI rendering.
17
+
18
+ ---
19
+
20
+ ## Before (v1, simplified)
21
+
22
+ ```diff
23
+ - 'use client';
24
+ -
25
+ - import { useState } from 'react';
26
+ - import {
27
+ - useXConnectors,
28
+ - useXConnect,
29
+ - useXDisconnect,
30
+ - type ChainType,
31
+ - } from '@sodax/wallet-sdk-react';
32
+ -
33
+ - const SUPPORTED_CHAINS: ChainType[] = ['EVM', 'SUI', 'SOLANA', 'ICON'];
34
+ -
35
+ - export function WalletModal({ open, onClose }: { open: boolean; onClose: () => void }) {
36
+ - const [pickedChain, setPickedChain] = useState<ChainType | null>(null);
37
+ - const [connectingId, setConnectingId] = useState<string | null>(null);
38
+ - const [error, setError] = useState<Error | null>(null);
39
+ -
40
+ - const evmConnectors = useXConnectors('EVM');
41
+ - const suiConnectors = useXConnectors('SUI');
42
+ - const solanaConnectors = useXConnectors('SOLANA');
43
+ - const iconConnectors = useXConnectors('ICON');
44
+ -
45
+ - const { mutateAsync: connect } = useXConnect();
46
+ - const disconnect = useXDisconnect();
47
+ -
48
+ - const connectorsByChain: Record<ChainType, ReturnType<typeof useXConnectors>> = {
49
+ - EVM: evmConnectors,
50
+ - SUI: suiConnectors,
51
+ - SOLANA: solanaConnectors,
52
+ - ICON: iconConnectors,
53
+ - };
54
+ -
55
+ - if (!open) return null;
56
+ -
57
+ - if (!pickedChain) {
58
+ - return (
59
+ - <Dialog onClose={onClose}>
60
+ - <h2>Select a chain</h2>
61
+ - {SUPPORTED_CHAINS.map((chain) => (
62
+ - <button key={chain} onClick={() => setPickedChain(chain)}>
63
+ - {chain}
64
+ - </button>
65
+ - ))}
66
+ - </Dialog>
67
+ - );
68
+ - }
69
+ -
70
+ - const connectors = connectorsByChain[pickedChain] ?? [];
71
+ -
72
+ - return (
73
+ - <Dialog onClose={onClose}>
74
+ - <button onClick={() => setPickedChain(null)}>← back</button>
75
+ - <h2>Connect to {pickedChain}</h2>
76
+ - {error && <div>Error: {error.message}</div>}
77
+ - {connectors.map((connector) => (
78
+ - <button
79
+ - key={connector.id}
80
+ - disabled={connectingId !== null}
81
+ - onClick={async () => {
82
+ - setConnectingId(connector.id);
83
+ - setError(null);
84
+ - try {
85
+ - await connect(connector);
86
+ - onClose();
87
+ - } catch (err) {
88
+ - setError(err as Error);
89
+ - } finally {
90
+ - setConnectingId(null);
91
+ - }
92
+ - }}
93
+ - >
94
+ - {connector.name}
95
+ - {connectingId === connector.id && ' (connecting...)'}
96
+ - </button>
97
+ - ))}
98
+ - </Dialog>
99
+ - );
100
+ - }
101
+ ```
102
+
103
+ (Most v1 modals look like this — manual chain list, manual loop over connectors, manual try/catch for state.)
104
+
105
+ ---
106
+
107
+ ## After (v2)
108
+
109
+ ```tsx
110
+ // @ai-snippets-skip
111
+ 'use client';
112
+
113
+ import {
114
+ useWalletModal,
115
+ useChainGroups,
116
+ sortConnectors,
117
+ } from '@sodax/wallet-sdk-react';
118
+
119
+ export function WalletModal({ open, onClose }: { open: boolean; onClose: () => void }) {
120
+ const modal = useWalletModal({
121
+ onConnected: () => onClose(),
122
+ });
123
+ const chainGroups = useChainGroups();
124
+
125
+ if (!open) return null;
126
+
127
+ switch (modal.state.kind) {
128
+ case 'closed':
129
+ case 'chainSelect':
130
+ return (
131
+ <Dialog onClose={onClose}>
132
+ <h2>Select a chain</h2>
133
+ {chainGroups.map((group) => (
134
+ <button
135
+ key={group.id}
136
+ onClick={() => modal.openChain(group.xChainType)}
137
+ >
138
+ {group.label}
139
+ </button>
140
+ ))}
141
+ </Dialog>
142
+ );
143
+
144
+ case 'walletSelect': {
145
+ const sorted = sortConnectors(modal.state.connectors, {
146
+ preferred: ['MetaMask', 'Phantom'],
147
+ });
148
+ return (
149
+ <Dialog onClose={onClose}>
150
+ <button onClick={() => modal.back()}>← back</button>
151
+ <h2>Connect to {modal.state.xChainType}</h2>
152
+ {sorted.map((connector) => (
153
+ <button
154
+ key={connector.id}
155
+ disabled={!connector.isInstalled}
156
+ onClick={() => modal.connect(connector)}
157
+ >
158
+ {connector.name}
159
+ {!connector.isInstalled && (
160
+ <a href={connector.installUrl} target="_blank" rel="noreferrer">
161
+ Install
162
+ </a>
163
+ )}
164
+ </button>
165
+ ))}
166
+ </Dialog>
167
+ );
168
+ }
169
+
170
+ case 'connecting':
171
+ return (
172
+ <Dialog onClose={onClose}>
173
+ <p>Connecting to {modal.state.connector.name}…</p>
174
+ </Dialog>
175
+ );
176
+
177
+ case 'error':
178
+ return (
179
+ <Dialog onClose={onClose}>
180
+ <p>Error: {modal.state.error.message}</p>
181
+ <button onClick={() => modal.retry()}>Retry</button>
182
+ </Dialog>
183
+ );
184
+
185
+ case 'success':
186
+ return null; // onConnected handler closes
187
+
188
+ default:
189
+ return null;
190
+ }
191
+ }
192
+ ```
193
+
194
+ ---
195
+
196
+ ## What changed
197
+
198
+ | Concern | v1 (manual) | v2 (primitive) |
199
+ |---|---|---|
200
+ | Track which chain is picked | `useState<ChainType \| null>` | `useWalletModal().state.kind === 'walletSelect'` |
201
+ | List enabled chains | hardcoded `SUPPORTED_CHAINS` | `useChainGroups()` (driven by `walletConfig`) |
202
+ | List connectors per chain | one `useXConnectors` per chain | `modal.state.connectors` when `kind === 'walletSelect'` |
203
+ | Connecting / error state | `useState` for `connectingId`, `error` | `modal.state.kind` with discriminated union |
204
+ | Retry on error | re-trigger click manually | `modal.retry()` |
205
+ | Filter to installed wallets | n/a | `connector.isInstalled` + `connector.installUrl` |
206
+ | Sort connectors | manual `array.sort` | `sortConnectors(xs, { preferred })` |
207
+ | Close on success | manual `onClose()` after `connect` | `useWalletModal({ onConnected })` callback |
208
+ | EVM treated as one | per-network confusion | `useChainGroups` collapses EVM into one row |
209
+
210
+ ---
211
+
212
+ ## Migration steps
213
+
214
+ 1. **Find the v1 modal file.** Search for `useState<ChainType` or multiple `useXConnectors` calls in the same component.
215
+ 2. **Replace state-tracking with `useWalletModal`.** Remove `useState` for picked chain, connectingId, error.
216
+ 3. **Replace hardcoded chain list with `useChainGroups`.** Use the `xChainType` field on each group entry.
217
+ 4. **Switch on `modal.state.kind`.** Render branches: `'closed'` / `'chainSelect'` / `'walletSelect'` / `'connecting'` / `'error'` / `'success'`.
218
+ 5. **Use connector metadata.** `connector.isInstalled` / `connector.installUrl` for install CTA. `sortConnectors` to rank installed wallets first.
219
+ 6. **Keep your existing `<Dialog>` primitive.** v2 is **headless** — bring your own UI components.
220
+
221
+ ---
222
+
223
+ ## Verification
224
+
225
+ ```bash
226
+ # 1. Type check
227
+ pnpm checkTs
228
+
229
+ # 2. Confirm no manual state is tracking modal flow
230
+ grep -nE "useState<ChainType" <user-modal-file>
231
+ grep -nE "useState.*connectingId|useState.*pickedChain" <user-modal-file>
232
+ # expect empty
233
+
234
+ # 3. Manual — open modal, walk through chain → wallet → connecting → success
235
+ ```
236
+
237
+ ---
238
+
239
+ ## Edge cases
240
+
241
+ - **Modal opens on a specific chain (skip chain select).** Call `modal.openChain('EVM')` directly in your trigger button instead of going through chain select. The state machine starts at `'walletSelect'` for that chain.
242
+ - **App needs to know which chain the user picked even before connecting.** Read `modal.state.xChainType` inside the `'walletSelect'` / `'connecting'` branches.
243
+ - **Multiple modal trigger buttons (e.g. chain-specific CTAs).** Reuse one `useWalletModal` instance — do not create one per button.
244
+
245
+ For a full integration walkthrough (without v1 baggage), see [`recipes/multi-chain-modal.md`](../../../integration/knowledge/recipes/multi-chain-modal.md).
@@ -0,0 +1,165 @@
1
+ # Recipe: Migrate Next.js SSR Setup
2
+
3
+ Migrates the SSR-specific provider setup. Both `initialState` and `reconnectOnMount` move **into the `EVM` slot** of the new `config` prop — they are not removed in v2. Self-contained — apply this recipe without reading other files.
4
+
5
+ ---
6
+
7
+ ## When to use this recipe
8
+
9
+ Apply when the user's v1 code:
10
+
11
+ - Passes `initialState={...}` to `SodaxWalletProvider`
12
+ - Has a server component or page that calls `cookieToInitialState` (wagmi)
13
+ - Sets `options.wagmi.ssr: true` and/or `options.wagmi.reconnectOnMount`
14
+
15
+ If the project is **not** Next.js (Vite, CRA), only the prop-shape rewrite applies; `initialState` plumbing is not needed.
16
+
17
+ ---
18
+
19
+ ## Before (v1)
20
+
21
+ ```diff
22
+ - // app/layout.tsx — v1 ❌
23
+ - import { headers } from 'next/headers';
24
+ - import { cookieToInitialState } from 'wagmi';
25
+ - import { SodaxWalletProvider } from '@sodax/wallet-sdk-react';
26
+ - import { createWagmiConfig } from '@sodax/wallet-sdk-react'; // hypothetical helper consumers used
27
+ -
28
+ - const rpcConfig = {
29
+ - 'sonic': 'https://rpc.soniclabs.com',
30
+ - '0x1.eth': 'https://ethereum-rpc.publicnode.com',
31
+ - };
32
+ -
33
+ - export default async function RootLayout({ children }: { children: React.ReactNode }) {
34
+ - const headersList = await headers();
35
+ - const cookie = headersList.get('cookie');
36
+ -
37
+ - // Build wagmi config the same way the package built it internally to derive initialState
38
+ - const wagmiConfig = createWagmiConfig(rpcConfig, { ssr: true });
39
+ - const initialState = cookieToInitialState(wagmiConfig, cookie);
40
+ -
41
+ - return (
42
+ - <html>
43
+ - <body>
44
+ - <SodaxWalletProvider
45
+ - rpcConfig={rpcConfig}
46
+ - options={{ wagmi: { ssr: true, reconnectOnMount: true } }}
47
+ - initialState={initialState}
48
+ - >
49
+ - {children}
50
+ - </SodaxWalletProvider>
51
+ - </body>
52
+ - </html>
53
+ - );
54
+ - }
55
+ ```
56
+
57
+ ---
58
+
59
+ ## After (v2)
60
+
61
+ ```tsx
62
+ // @ai-snippets-skip
63
+ // app/layout.tsx — v2 ✅
64
+ import { headers } from 'next/headers';
65
+ import { cookieToInitialState } from 'wagmi';
66
+ import { ChainKeys } from '@sodax/types';
67
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
68
+ import { SodaxWalletProvider, type SodaxWalletConfig } from '@sodax/wallet-sdk-react';
69
+ import { createWagmiConfig } from '@sodax/wallet-sdk-react/xchains/evm';
70
+
71
+ const walletConfig: SodaxWalletConfig = {
72
+ EVM: {
73
+ ssr: true,
74
+ reconnectOnMount: true,
75
+ chains: {
76
+ [ChainKeys.SONIC_MAINNET]: { rpcUrl: 'https://rpc.soniclabs.com' },
77
+ [ChainKeys.ETHEREUM_MAINNET]: { rpcUrl: 'https://ethereum-rpc.publicnode.com' },
78
+ },
79
+ },
80
+ // Add other chain slots as needed
81
+ };
82
+
83
+ const queryClient = new QueryClient();
84
+
85
+ export default async function RootLayout({ children }: { children: React.ReactNode }) {
86
+ const cookie = (await headers()).get('cookie');
87
+ // Re-derive initialState from cookies to avoid disconnect-flash on first render.
88
+ const wagmiConfig = createWagmiConfig(walletConfig.EVM!);
89
+ const initialState = cookieToInitialState(wagmiConfig, cookie);
90
+
91
+ const evmConfig = { ...walletConfig.EVM!, initialState };
92
+ const config: SodaxWalletConfig = { ...walletConfig, EVM: evmConfig };
93
+
94
+ return (
95
+ <html>
96
+ <body>
97
+ <QueryClientProvider client={queryClient}>
98
+ <SodaxWalletProvider config={config}>{children}</SodaxWalletProvider>
99
+ </QueryClientProvider>
100
+ </body>
101
+ </html>
102
+ );
103
+ }
104
+ ```
105
+
106
+ If you don't need to avoid the first-render disconnect flash, drop the cookie / `initialState` plumbing entirely — `EVM.ssr: true` alone is enough for the typical SSR app.
107
+
108
+ ---
109
+
110
+ ## What changed
111
+
112
+ | Concern | v1 | v2 |
113
+ |---|---|---|
114
+ | `rpcConfig` flat dict | top-level prop | nested under `EVM.chains[<ChainKey>].rpcUrl` |
115
+ | `options.wagmi.ssr` | nested under `options.wagmi` | `EVM.ssr: true` |
116
+ | `options.wagmi.reconnectOnMount` | nested under `options.wagmi` | `EVM.reconnectOnMount` (still supported, default `false`) |
117
+ | `initialState` | top-level prop | `EVM.initialState` (still supported — pass `cookieToInitialState(...)` for Next.js cookie hydration) |
118
+ | `QueryClient` | created internally by `SodaxWalletProvider` | created by caller, wrapped with `QueryClientProvider` |
119
+
120
+ ---
121
+
122
+ ## Migration steps
123
+
124
+ 1. **Move per-chain RPC URLs.** Move `rpcConfig['sonic']` etc. into `EVM.chains[ChainKeys.SONIC_MAINNET].rpcUrl`. Use `ChainKeys` constants from `@sodax/types`.
125
+ 2. **Collapse `options.wagmi.*` into `EVM.*`.** `options.wagmi.ssr` → `EVM.ssr`, `options.wagmi.reconnectOnMount` → `EVM.reconnectOnMount`.
126
+ 3. **Move `initialState` into `EVM.initialState`.** v2 still accepts wagmi cookie state; the prop name and location changed, not the feature.
127
+ 4. **Add `QueryClientProvider`.** Create a `QueryClient` (top-level module constant — singleton across renders) and wrap `SodaxWalletProvider` with `<QueryClientProvider>`.
128
+ 5. **Make sure `@tanstack/react-query` is a direct dep.** Add it if missing:
129
+ ```bash
130
+ pnpm add @tanstack/react-query
131
+ ```
132
+ 6. **Confirm consumer components are `'use client'`.** Hooks (`useXAccount`, `useXConnect`, etc.) only run on the client — any component that calls them needs the directive.
133
+
134
+ ---
135
+
136
+ ## Verification
137
+
138
+ ```bash
139
+ # 1. Type check
140
+ pnpm checkTs
141
+
142
+ # 2. No top-level v1 props remain on SodaxWalletProvider
143
+ grep -rnE "SodaxWalletProvider[^>]*\b(rpcConfig|options|initialState)\s*=" <user-src>
144
+ # expect empty
145
+
146
+ # 3. EVM.ssr: true is set
147
+ grep -rnE "EVM:\s*\{[^}]*\bssr:\s*true" <user-src>
148
+ # expect at least one match
149
+
150
+ # 4. QueryClientProvider wraps SodaxWalletProvider
151
+ # (manual — open layout.tsx, confirm nesting)
152
+
153
+ # 5. Manual — pnpm build && pnpm start, load page, confirm no hydration mismatch warnings in console
154
+ ```
155
+
156
+ ---
157
+
158
+ ## Common pitfalls
159
+
160
+ - **Forgetting `'use client'` on consumer components.** If you call `useXAccount` / `useXConnect` in a Server Component, you'll get "useEffect cannot be called from a server component". Wrap the consumer in a client component.
161
+ - **Creating `QueryClient` inside the layout component.** Each render creates a new client and React Query loses its cache. Define `queryClient` as a **module-level constant**, or use `useState(() => new QueryClient())` inside a client component.
162
+ - **Pages Router project.** This recipe assumes App Router. For Pages Router, mount the providers in `_app.tsx` instead — the API is the same.
163
+ - **Dynamic RPC URLs from env vars.** If `rpcUrl` comes from `process.env.NEXT_PUBLIC_*`, ensure the env var is available at module init time (it is, by Next.js convention). Don't compute the config inside a hook — `SodaxWalletProvider` freezes config on first render, so config must be stable.
164
+
165
+