@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,259 @@
1
+ # Recipe: Chain & Wallet Detection
2
+
3
+ Aggregate views over the wallet store — what's enabled, what's connected, what's installed. Use these hooks to render chain pickers, "manage connections" panels, install CTAs, and hydration-safe UIs.
4
+
5
+ **Depends on:** [`setup.md`](./setup.md)
6
+
7
+ ---
8
+
9
+ ## Hooks at a glance
10
+
11
+ | Hook | Purpose |
12
+ |------|---------|
13
+ | `useEnabledChains()` | List chain types mounted in `SodaxWalletProvider` config |
14
+ | `useChainGroups({ order? })` | One row per enabled chain (with display + connection metadata) — for chain pickers |
15
+ | `useConnectedChains({ order? })` | List of currently-connected chains + hydration `status` — for "manage connections" |
16
+ | `useIsWalletInstalled({ connectors?, chainType? })` | Cross-chain install check — for gating "Install X" CTA |
17
+
18
+ EVM **collapses to a single row** — wagmi maintains one connection across every configured EVM network.
19
+
20
+ ---
21
+
22
+ ## `useEnabledChains` — what's mounted
23
+
24
+ ```tsx
25
+ import { useEnabledChains } from '@sodax/wallet-sdk-react';
26
+
27
+ const enabled = useEnabledChains();
28
+ // e.g. ['EVM', 'SOLANA', 'BITCOIN']
29
+ ```
30
+
31
+ Returns the slot keys in `SodaxWalletConfig` (`config.EVM`, `config.SOLANA`, …), not which chains have a wallet connected. Use cases:
32
+
33
+ - Render only chain rows the dApp opted into.
34
+ - Cross-reference with `useXConnections()` to compute "of N enabled chains, M are connected".
35
+ - Drive `<Tabs>` / `<Select>` UIs without hard-coding a list.
36
+
37
+ `useChainGroups` and `useConnectedChains` already filter by `useEnabledChains` internally — reach for it directly only when you need the raw list.
38
+
39
+ ---
40
+
41
+ ## `useChainGroups` — chain picker model
42
+
43
+ One `ChainGroup` per enabled chain type, with display metadata + connection status. Designed for the "select a chain" step in modals.
44
+
45
+ ```tsx
46
+ 'use client';
47
+
48
+ import { useChainGroups } from '@sodax/wallet-sdk-react';
49
+ import type { ChainType } from '@sodax/types';
50
+
51
+ export function ChainPicker({ onPick }: { onPick: (c: ChainType) => void }) {
52
+ const groups = useChainGroups({ order: ['EVM', 'SOLANA', 'BITCOIN', 'ICON'] });
53
+
54
+ return (
55
+ <ul>
56
+ {groups.map((group) => (
57
+ <li key={group.chainType}>
58
+ <button onClick={() => onPick(group.chainType)}>
59
+ {group.iconUrl && <img src={group.iconUrl} alt="" width={24} height={24} />}
60
+ <span>{group.displayName}</span>
61
+ {group.isConnected && <span className="badge">Connected</span>}
62
+ </button>
63
+ </li>
64
+ ))}
65
+ </ul>
66
+ );
67
+ }
68
+ ```
69
+
70
+ ### `ChainGroup` shape
71
+
72
+ | Field | Type | Source |
73
+ |-------|------|--------|
74
+ | `chainType` | `ChainType` | The slot key (`'EVM'`, `'SOLANA'`, …) |
75
+ | `chainIds` | `readonly SpokeChainKey[]` | All chain keys sharing this `chainType` (e.g. all 12 EVM `ChainKeys.*` for `'EVM'`) |
76
+ | `displayName` | `string` | Default per-chain display name |
77
+ | `iconUrl` | `string \| undefined` | `undefined` = SDK doesn't ship one — provide your own |
78
+ | `isConnected` | `boolean` | `true` when an account is connected for this chain |
79
+ | `account` | `XAccount \| undefined` | Connected account |
80
+ | `connectorId` | `string \| undefined` | Active connector id when connected |
81
+
82
+ EVM's `chainIds` lists every configured EVM `ChainKey`, but the group itself is **one row**. Per-network switching belongs to [`switch-chain.md`](./switch-chain.md), not a separate group.
83
+
84
+ ---
85
+
86
+ ## `useConnectedChains` — connected list with hydration gate
87
+
88
+ Returns one entry per **currently-connected** chain (skipping the rest), with enriched connector metadata for "manage connections" UIs and status badges.
89
+
90
+ ```tsx
91
+ // @ai-snippets-skip
92
+ 'use client';
93
+
94
+ import { useConnectedChains } from '@sodax/wallet-sdk-react';
95
+
96
+ export function ConnectionList() {
97
+ const { chains, total, status } = useConnectedChains();
98
+
99
+ if (status === 'loading') return <Skeleton />;
100
+ if (total === 0) return <ConnectCta />;
101
+
102
+ return (
103
+ <ul>
104
+ {chains.map((chain) => (
105
+ <li key={chain.chainType}>
106
+ {chain.connectorIcon && <img src={chain.connectorIcon} alt="" />}
107
+ <span>{chain.connectorName ?? chain.connectorId}</span>
108
+ <code>{chain.account.address}</code>
109
+ </li>
110
+ ))}
111
+ </ul>
112
+ );
113
+ }
114
+ ```
115
+
116
+ ### `ConnectedChain` shape
117
+
118
+ | Field | Type | Notes |
119
+ |-------|------|-------|
120
+ | `chainType` | `ChainType` | |
121
+ | `account` | `XAccount` | Always populated (only included when address is non-empty) |
122
+ | `connectorId` | `string` | The persisted active connector |
123
+ | `connectorName` | `string \| undefined` | Looked up in `xConnectorsByChain` |
124
+ | `connectorIcon` | `string \| undefined` | |
125
+
126
+ ### Result shape
127
+
128
+ ```typescript
129
+ type UseConnectedChainsResult = {
130
+ chains: ConnectedChain[];
131
+ total: number;
132
+ status: 'loading' | 'ready';
133
+ };
134
+ ```
135
+
136
+ ---
137
+
138
+ ## `useIsWalletInstalled` — install detection
139
+
140
+ Read hook for gating "Connect" buttons on actual installation. Same identifier matching as `useBatchConnect` — see [`batch-operations.md`](./batch-operations.md).
141
+
142
+ ```typescript
143
+ import { useIsWalletInstalled } from '@sodax/wallet-sdk-react';
144
+
145
+ // True if any Hana variant is installed across all enabled chains
146
+ const hasHana = useIsWalletInstalled({ connectors: ['hana'] });
147
+
148
+ // True if any wallet is installed for Bitcoin specifically
149
+ const hasBitcoinWallet = useIsWalletInstalled({ chainType: 'BITCOIN' });
150
+
151
+ // AND filter — Hana specifically on EVM
152
+ const hanaOnEvm = useIsWalletInstalled({ connectors: ['hana'], chainType: 'EVM' });
153
+ ```
154
+
155
+ The type union enforces at compile time that **at least one of `connectors` / `chainType`** is present — `useIsWalletInstalled({})` is a type error. `connectors: []` is explicit "match nothing" — returns `false`.
156
+
157
+ ---
158
+
159
+ ## Hydration status — gate reload flicker
160
+
161
+ `useConnectedChains` exposes `status: 'loading' | 'ready'`. Use it to avoid the "Connect wallet" → "Connected" flash on page reload while Zustand rehydrates from `localStorage`:
162
+
163
+ ```tsx
164
+ // @ai-snippets-skip
165
+ const { chains, status } = useConnectedChains();
166
+
167
+ // ❌ Flicker — `chains` is empty for one render before hydration completes
168
+ return chains.length >= 1 ? <Connected /> : <ConnectCta />;
169
+
170
+ // ✅ No flicker — wait for hydration before deciding
171
+ return status === 'loading'
172
+ ? <Skeleton />
173
+ : chains.length >= 1 ? <Connected /> : <ConnectCta />;
174
+ ```
175
+
176
+ For first-paint correctness in SSR (Next.js), prefer `useConnectedChains.status` over an ad-hoc `useEffect(() => setMounted(true), [])` pattern — it's the official hydration signal.
177
+
178
+ `useChainGroups` does **not** expose this flag — its outputs are stable across hydration because connection-status fields (`isConnected`, `account`) start as `false` / `undefined` and gain values atomically when the persist middleware finishes.
179
+
180
+ ---
181
+
182
+ ## Display ordering
183
+
184
+ Both `useChainGroups` and `useConnectedChains` accept an `order?: readonly ChainType[]`:
185
+
186
+ 1. Chains in the array render in array order.
187
+ 2. Chains **not** in the array fall to the bottom, sorted alphabetically.
188
+ 3. Without `order`:
189
+ - `useChainGroups` follows the order of slots in `walletConfig` (config object key order).
190
+ - `useConnectedChains` follows `ChainTypeArr` from `@sodax/types` — stable across reloads.
191
+
192
+ ```typescript
193
+ const groups = useChainGroups({ order: ['EVM', 'ICON'] });
194
+ // EVM → ICON → (alphabetical: BITCOIN, INJECTIVE, NEAR, SOLANA, STACKS, STELLAR, SUI)
195
+ ```
196
+
197
+ For UIs that must not reflow on reload (header chain list, navigation), always pass `order`.
198
+
199
+ ---
200
+
201
+ ## Common patterns
202
+
203
+ ### Pattern 1 — header connected-account chip
204
+
205
+ ```tsx
206
+ // @ai-snippets-skip
207
+ function HeaderAccountChip() {
208
+ const { chains, status } = useConnectedChains();
209
+
210
+ if (status === 'loading') return null;
211
+ if (chains.length === 0) return <ConnectButton />;
212
+
213
+ return <span>{chains.length} chain{chains.length !== 1 ? 's' : ''} connected</span>;
214
+ }
215
+ ```
216
+
217
+ ### Pattern 2 — "install Hana" CTA when not installed
218
+
219
+ ```tsx
220
+ // @ai-snippets-skip
221
+ function HanaCta() {
222
+ const installed = useIsWalletInstalled({ connectors: ['hana'] });
223
+ return installed ? null : (
224
+ <a href="https://hana-wallet.com" target="_blank" rel="noreferrer">
225
+ Install Hana Wallet
226
+ </a>
227
+ );
228
+ }
229
+ ```
230
+
231
+ ### Pattern 3 — chain selector in swap form
232
+
233
+ ```tsx
234
+ // @ai-snippets-skip
235
+ function ChainSelector({ value, onChange }: { value: ChainType; onChange: (c: ChainType) => void }) {
236
+ const groups = useChainGroups({ order: ['EVM', 'SOLANA', 'SUI'] });
237
+ return (
238
+ <select value={value} onChange={(e) => onChange(e.target.value as ChainType)}>
239
+ {groups.map((g) => (
240
+ <option key={g.chainType} value={g.chainType}>
241
+ {g.displayName} {g.isConnected ? '✓' : ''}
242
+ </option>
243
+ ))}
244
+ </select>
245
+ );
246
+ }
247
+ ```
248
+
249
+ ---
250
+
251
+ ## Verification
252
+
253
+ ```bash
254
+ # 1. Type check
255
+ pnpm checkTs
256
+
257
+ # 2. Manual — load page on slow 3G, confirm no Connect→Connected flash on reload
258
+ # 3. Manual — uninstall Hana, confirm CTA appears; reinstall, confirm CTA disappears
259
+ ```
@@ -0,0 +1,159 @@
1
+ # Recipe: Connect Button
2
+
3
+ Single-chain connect/disconnect button — pick a connector, connect, read the account, disconnect. Self-contained.
4
+
5
+ **Depends on:** [`setup.md`](./setup.md)
6
+
7
+ ---
8
+
9
+ ## Hooks used
10
+
11
+ | Hook | Purpose |
12
+ |------|---------|
13
+ | `useXConnectors({ xChainType })` | List available connectors for the chain family |
14
+ | `useXConnect()` | React Query mutation — `mutate(connector)` |
15
+ | `useXAccount({ xChainType })` | Read connected account (always returns object — `address` is `undefined` when disconnected) |
16
+ | `useXDisconnect()` | Returns `(xChainType) => Promise<void>` |
17
+ | `sortConnectors(list, { preferred })` | Optional — rank installed/preferred wallets first |
18
+
19
+ ---
20
+
21
+ ## Connect button
22
+
23
+ ```tsx
24
+ 'use client';
25
+
26
+ import {
27
+ useXConnectors,
28
+ useXConnect,
29
+ useXAccount,
30
+ useXDisconnect,
31
+ sortConnectors,
32
+ type IXConnector,
33
+ } from '@sodax/wallet-sdk-react';
34
+
35
+ const PREFERRED = ['hana', 'metamask'] as const;
36
+
37
+ export function EvmConnectButton() {
38
+ const raw = useXConnectors({ xChainType: 'EVM' });
39
+ const connectors = sortConnectors(raw, { preferred: PREFERRED });
40
+ const { mutateAsync: connect, isPending, error } = useXConnect();
41
+ const account = useXAccount({ xChainType: 'EVM' });
42
+ const disconnect = useXDisconnect();
43
+
44
+ if (account.address) {
45
+ return (
46
+ <div>
47
+ <code>{account.address}</code>
48
+ <button onClick={() => disconnect({ xChainType: 'EVM' })}>Disconnect</button>
49
+ </div>
50
+ );
51
+ }
52
+
53
+ return (
54
+ <div>
55
+ {connectors.map((connector) => (
56
+ <button
57
+ key={connector.id}
58
+ onClick={() => connect(connector).catch(() => {})}
59
+ disabled={isPending}
60
+ >
61
+ {connector.icon && <img src={connector.icon} alt="" width={20} height={20} />}
62
+ {connector.name}
63
+ {!connector.isInstalled && ' (not installed)'}
64
+ </button>
65
+ ))}
66
+ {error && <p style={{ color: 'red' }}>{error.message}</p>}
67
+ </div>
68
+ );
69
+ }
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Install CTA for missing wallets
75
+
76
+ ```tsx
77
+ // @ai-snippets-skip
78
+ {connectors.map((connector) =>
79
+ connector.isInstalled ? (
80
+ <button key={connector.id} onClick={() => connect(connector)}>
81
+ {connector.name}
82
+ </button>
83
+ ) : (
84
+ <a key={connector.id} href={connector.installUrl} target="_blank" rel="noreferrer">
85
+ Install {connector.name}
86
+ </a>
87
+ ),
88
+ )}
89
+ ```
90
+
91
+ `isInstalled` reads `window.*` at render time (no extra subscription). For batch install detection across wallet brands, use `useIsWalletInstalled` — see [`batch-operations.md`](./batch-operations.md).
92
+
93
+ ---
94
+
95
+ ## Caveat — provider-managed chains resolve with `undefined`
96
+
97
+ For EVM, Solana, and Sui, `connect(connector)` resolves with `undefined` because connection state is set asynchronously after the native SDK adapter reports `connected`. Always read the account via `useXAccount`, not the mutation's return value:
98
+
99
+ ```typescript
100
+ const { mutateAsync: connect } = useXConnect();
101
+ const account = useXAccount({ xChainType: 'EVM' });
102
+
103
+ await connect(connector); // resolves with undefined for EVM
104
+ // account.address is populated on the next render
105
+ ```
106
+
107
+ Non-provider chains (Bitcoin, ICON, Injective, Stellar, NEAR, Stacks) return the resolved `XAccount` from `connect()` — but reading via `useXAccount` works for both, so default to it.
108
+
109
+ ---
110
+
111
+ ## Multiple chains, one button
112
+
113
+ For a "connect EVM + Solana + Bitcoin in one click" pattern, use [`batch-operations.md`](./batch-operations.md):
114
+
115
+ ```tsx
116
+ import { useBatchConnect } from '@sodax/wallet-sdk-react';
117
+
118
+ const { run, status } = useBatchConnect({ connectors: ['hana'] });
119
+ // Connects every chain Hana supports — sequential, errors collected.
120
+ <button onClick={run} disabled={status === 'running'}>
121
+ Connect Hana on all chains
122
+ </button>;
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Variations
128
+
129
+ ### Per-chain-id button (e.g. one button per EVM network)
130
+
131
+ ⚠️ Not recommended for EVM — wagmi treats EVM as a **single connection across every configured network**. A per-Ethereum button rarely matches user expectations. If you really need per-chain-id resolution:
132
+
133
+ ```tsx
134
+ // @ai-snippets-skip
135
+ import { ChainKeys } from '@sodax/types';
136
+
137
+ const account = useXAccount({ xChainId: ChainKeys.ETHEREUM_MAINNET });
138
+ ```
139
+
140
+ ### Sui / Solana / etc.
141
+
142
+ Replace `'EVM'` with the chain type the button targets:
143
+
144
+ ```tsx
145
+ // @ai-snippets-skip
146
+ const connectors = useXConnectors({ xChainType: 'SUI' });
147
+ const { address } = useXAccount({ xChainType: 'SUI' });
148
+ ```
149
+
150
+ ---
151
+
152
+ ## Verification
153
+
154
+ ```bash
155
+ # 1. Type check
156
+ pnpm checkTs
157
+
158
+ # 2. Manual — load page, click connect, confirm address renders, reload page, confirm connection survives
159
+ ```
@@ -0,0 +1,203 @@
1
+ # Recipe: Multi-Chain Wallet Modal
2
+
3
+ Headless wallet-connect modal that walks the user through `chainSelect → walletSelect → connecting → success | error`. Pair with `useChainGroups` for the chain picker and `useXConnectors` for the wallet picker. Render-agnostic — works with any dialog/drawer/inline UI.
4
+
5
+ **Depends on:** [`setup.md`](./setup.md)
6
+
7
+ ---
8
+
9
+ ## Hooks used
10
+
11
+ | Hook | Purpose |
12
+ |------|---------|
13
+ | `useWalletModal({ onConnected? })` | State machine + actions (`open`, `close`, `back`, `selectChain`, `selectWallet`, `retry`) |
14
+ | `useChainGroups({ order? })` | One row per enabled chain family (EVM collapses to one row) |
15
+ | `useXConnectors({ xChainType })` | Wallet list for the chosen chain family |
16
+ | `useXAccount({ xChainType })` | Read the connected account when needed |
17
+
18
+ ---
19
+
20
+ ## Render switch
21
+
22
+ ```tsx
23
+ // @ai-snippets-skip
24
+ 'use client';
25
+
26
+ import {
27
+ useWalletModal,
28
+ useChainGroups,
29
+ useXConnectors,
30
+ type IXConnector,
31
+ } from '@sodax/wallet-sdk-react';
32
+
33
+ export function WalletModalRoot() {
34
+ const modal = useWalletModal({
35
+ onConnected: async (chainType, account) => {
36
+ console.log('connected', chainType, account.address);
37
+ },
38
+ });
39
+
40
+ switch (modal.state.kind) {
41
+ case 'closed':
42
+ return <button onClick={modal.open}>Connect Wallet</button>;
43
+
44
+ case 'chainSelect':
45
+ return <ChainPicker onPick={modal.selectChain} onClose={modal.close} />;
46
+
47
+ case 'walletSelect':
48
+ return (
49
+ <WalletPicker
50
+ chainType={modal.state.chainType}
51
+ onPick={modal.selectWallet}
52
+ onBack={modal.back}
53
+ onClose={modal.close}
54
+ />
55
+ );
56
+
57
+ case 'connecting':
58
+ // Hide modal while wagmi's QR modal is up for WalletConnect
59
+ if (modal.state.connector.id === 'walletConnect') return null;
60
+ return (
61
+ <Dialog onClose={modal.close}>
62
+ <p>Approve in {modal.state.connector.name}…</p>
63
+ <button onClick={modal.back}>Cancel</button>
64
+ </Dialog>
65
+ );
66
+
67
+ case 'success':
68
+ // onConnected fired; close after a beat
69
+ setTimeout(modal.close, 0);
70
+ return null;
71
+
72
+ case 'error':
73
+ return (
74
+ <Dialog onClose={modal.close}>
75
+ <p>{modal.state.error.message}</p>
76
+ {!modal.state.connector.isInstalled && modal.state.connector.installUrl && (
77
+ <a href={modal.state.connector.installUrl}>Install {modal.state.connector.name}</a>
78
+ )}
79
+ <button onClick={modal.retry}>Retry</button>
80
+ <button onClick={modal.back}>Pick another wallet</button>
81
+ </Dialog>
82
+ );
83
+ }
84
+ }
85
+ ```
86
+
87
+ Render `<WalletModalRoot />` once at the app root — any other component can dispatch `useWalletModal().open()` to show it.
88
+
89
+ ---
90
+
91
+ ## Chain picker
92
+
93
+ ```tsx
94
+ // @ai-snippets-skip
95
+ import { useChainGroups } from '@sodax/wallet-sdk-react';
96
+ import type { ChainType } from '@sodax/types';
97
+
98
+ function ChainPicker({ onPick, onClose }: { onPick: (c: ChainType) => void; onClose: () => void }) {
99
+ const groups = useChainGroups({ order: ['EVM', 'SOLANA', 'BITCOIN', 'ICON'] });
100
+
101
+ return (
102
+ <Dialog onClose={onClose}>
103
+ <h2>Select a chain</h2>
104
+ {groups.map((group) => (
105
+ <button key={group.chainType} onClick={() => onPick(group.chainType)}>
106
+ {group.iconUrl && <img src={group.iconUrl} alt="" width={24} height={24} />}
107
+ <span>{group.displayName}</span>
108
+ {group.isConnected && <span>Connected</span>}
109
+ </button>
110
+ ))}
111
+ </Dialog>
112
+ );
113
+ }
114
+ ```
115
+
116
+ EVM collapses to a single group covering every configured EVM network — this matches reality (wagmi maintains one connection across all EVM chains).
117
+
118
+ ---
119
+
120
+ ## Wallet picker
121
+
122
+ ```tsx
123
+ // @ai-snippets-skip
124
+ import { useXConnectors, sortConnectors, type IXConnector } from '@sodax/wallet-sdk-react';
125
+ import type { ChainType } from '@sodax/types';
126
+
127
+ function WalletPicker({
128
+ chainType,
129
+ onPick,
130
+ onBack,
131
+ onClose,
132
+ }: {
133
+ chainType: ChainType;
134
+ onPick: (c: IXConnector) => void;
135
+ onBack: () => void;
136
+ onClose: () => void;
137
+ }) {
138
+ const connectors = sortConnectors(useXConnectors({ xChainType: chainType }), {
139
+ preferred: ['hana', 'metamask', 'phantom'],
140
+ });
141
+
142
+ return (
143
+ <Dialog onClose={onClose}>
144
+ <button onClick={onBack}>← Back</button>
145
+ <h2>Select a wallet</h2>
146
+ {connectors.map((connector) => (
147
+ <button key={connector.id} onClick={() => onPick(connector)}>
148
+ {connector.icon && <img src={connector.icon} alt="" />}
149
+ {connector.name}
150
+ {!connector.isInstalled && ' (not installed)'}
151
+ </button>
152
+ ))}
153
+ </Dialog>
154
+ );
155
+ }
156
+ ```
157
+
158
+ ---
159
+
160
+ ## Concurrency rules
161
+
162
+ - **Same connector double-click** → returns the same in-flight promise (no double popup).
163
+ - **Different connector mid-attempt** → starts a new attempt; previous one's late resolution is dropped.
164
+ - **`back()` / `close()` mid-attempt** → cancellation guard inside the modal layer; the wallet may still approve in the background but `success`/`error` won't fire. To roll back, call `useXDisconnect()(xChainType)` from the same handler.
165
+
166
+ ---
167
+
168
+ ## `onConnected` is non-fatal
169
+
170
+ Throwing inside `onConnected` is logged but **does not** downgrade `success` → `error`. The connection is already persisted; the user is genuinely connected.
171
+
172
+ ---
173
+
174
+ ## Non-modal alternative — `useConnectionFlow`
175
+
176
+ For a single-button flow without the multi-step modal:
177
+
178
+ ```tsx
179
+ // @ai-snippets-skip
180
+ import { useConnectionFlow } from '@sodax/wallet-sdk-react';
181
+
182
+ const { status, error, connect, retry, activeConnector } = useConnectionFlow();
183
+
184
+ return (
185
+ <button onClick={() => connect(connector)} disabled={status === 'connecting'}>
186
+ {status === 'connecting' ? 'Waiting…' : 'Connect'}
187
+ </button>
188
+ );
189
+ ```
190
+
191
+ `connect()` and `retry()` never throw — errors flow into `error` state.
192
+
193
+ ---
194
+
195
+ ## Verification
196
+
197
+ ```bash
198
+ # 1. Type check
199
+ pnpm checkTs
200
+
201
+ # 2. Manual — open modal, walk through chain → wallet → connecting → success → close
202
+ # 3. Manual — pick non-installed wallet, confirm install link appears in error state
203
+ ```