@sodax/dapp-kit 1.5.7-beta → 2.0.0-rc.1

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/README.md +300 -422
  2. package/ai-exported/AGENTS.md +134 -0
  3. package/ai-exported/integration/README.md +49 -0
  4. package/ai-exported/integration/ai-rules.md +79 -0
  5. package/ai-exported/integration/architecture.md +274 -0
  6. package/ai-exported/integration/features/README.md +29 -0
  7. package/ai-exported/integration/features/auxiliary-services.md +169 -0
  8. package/ai-exported/integration/features/bitcoin.md +87 -0
  9. package/ai-exported/integration/features/bridge.md +91 -0
  10. package/ai-exported/integration/features/dex.md +152 -0
  11. package/ai-exported/integration/features/migration.md +118 -0
  12. package/ai-exported/integration/features/money-market.md +116 -0
  13. package/ai-exported/integration/features/staking.md +123 -0
  14. package/ai-exported/integration/features/swap.md +101 -0
  15. package/ai-exported/integration/quickstart.md +187 -0
  16. package/ai-exported/integration/recipes/README.md +136 -0
  17. package/ai-exported/integration/recipes/backend-queries.md +157 -0
  18. package/ai-exported/integration/recipes/bitcoin.md +193 -0
  19. package/ai-exported/integration/recipes/bridge.md +174 -0
  20. package/ai-exported/integration/recipes/dex.md +204 -0
  21. package/ai-exported/integration/recipes/invalidations.md +115 -0
  22. package/ai-exported/integration/recipes/migration.md +212 -0
  23. package/ai-exported/integration/recipes/money-market.md +206 -0
  24. package/ai-exported/integration/recipes/mutation-error-handling.md +118 -0
  25. package/ai-exported/integration/recipes/observability.md +93 -0
  26. package/ai-exported/integration/recipes/setup.md +144 -0
  27. package/ai-exported/integration/recipes/staking.md +202 -0
  28. package/ai-exported/integration/recipes/swap.md +272 -0
  29. package/ai-exported/integration/recipes/wallet-connectivity.md +101 -0
  30. package/ai-exported/integration/reference/README.md +12 -0
  31. package/ai-exported/integration/reference/glossary.md +188 -0
  32. package/ai-exported/integration/reference/hooks-index.md +194 -0
  33. package/ai-exported/integration/reference/public-api.md +110 -0
  34. package/ai-exported/integration/reference/querykey-conventions.md +179 -0
  35. package/ai-exported/migration/README.md +60 -0
  36. package/ai-exported/migration/ai-rules.md +81 -0
  37. package/ai-exported/migration/breaking-changes/hook-signatures.md +233 -0
  38. package/ai-exported/migration/breaking-changes/querykey-conventions.md +108 -0
  39. package/ai-exported/migration/breaking-changes/result-handling.md +211 -0
  40. package/ai-exported/migration/breaking-changes/sdk-leakage.md +165 -0
  41. package/ai-exported/migration/checklist.md +89 -0
  42. package/ai-exported/migration/features/README.md +34 -0
  43. package/ai-exported/migration/features/auxiliary-services.md +114 -0
  44. package/ai-exported/migration/features/bitcoin.md +88 -0
  45. package/ai-exported/migration/features/bridge.md +123 -0
  46. package/ai-exported/migration/features/dex.md +101 -0
  47. package/ai-exported/migration/features/migration.md +120 -0
  48. package/ai-exported/migration/features/money-market.md +97 -0
  49. package/ai-exported/migration/features/staking.md +109 -0
  50. package/ai-exported/migration/features/swap.md +118 -0
  51. package/ai-exported/migration/recipes.md +188 -0
  52. package/ai-exported/migration/reference/README.md +15 -0
  53. package/ai-exported/migration/reference/deleted-hooks.md +110 -0
  54. package/ai-exported/migration/reference/error-shape-crosswalk.md +144 -0
  55. package/ai-exported/migration/reference/renamed-hooks.md +66 -0
  56. package/dist/index.cjs +2642 -0
  57. package/dist/index.cjs.map +1 -0
  58. package/dist/index.d.cts +1550 -0
  59. package/dist/index.d.ts +1020 -2051
  60. package/dist/index.mjs +1581 -1531
  61. package/dist/index.mjs.map +1 -1
  62. package/package.json +20 -10
  63. package/src/contexts/index.ts +0 -3
  64. package/src/hooks/_mutationContract.test.ts +99 -0
  65. package/src/hooks/backend/README.md +2 -2
  66. package/src/hooks/backend/index.ts +13 -13
  67. package/src/hooks/backend/unwrapResult.ts +1 -0
  68. package/src/hooks/backend/useBackendAllMoneyMarketAssets.ts +13 -45
  69. package/src/hooks/backend/useBackendAllMoneyMarketBorrowers.ts +29 -59
  70. package/src/hooks/backend/useBackendIntentByHash.ts +21 -47
  71. package/src/hooks/backend/useBackendIntentByTxHash.ts +23 -50
  72. package/src/hooks/backend/useBackendMoneyMarketAsset.ts +21 -54
  73. package/src/hooks/backend/useBackendMoneyMarketAssetBorrowers.ts +30 -57
  74. package/src/hooks/backend/useBackendMoneyMarketAssetSuppliers.ts +31 -58
  75. package/src/hooks/backend/useBackendMoneyMarketPosition.ts +22 -38
  76. package/src/hooks/backend/useBackendOrderbook.ts +27 -49
  77. package/src/hooks/backend/useBackendSubmitSwapTx.ts +30 -36
  78. package/src/hooks/backend/useBackendSubmitSwapTxStatus.ts +38 -58
  79. package/src/hooks/backend/useBackendUserIntents.ts +25 -63
  80. package/src/hooks/bitcoin/index.ts +9 -8
  81. package/src/hooks/bitcoin/useBitcoinBalance.ts +20 -5
  82. package/src/hooks/bitcoin/useExpiredUtxos.ts +26 -16
  83. package/src/hooks/bitcoin/useFundTradingWallet.ts +33 -30
  84. package/src/hooks/bitcoin/useRadfiAuth.ts +43 -40
  85. package/src/hooks/bitcoin/useRadfiSession.ts +53 -59
  86. package/src/hooks/bitcoin/useRadfiWithdraw.ts +35 -53
  87. package/src/hooks/bitcoin/useRenewUtxos.ts +30 -50
  88. package/src/hooks/bitcoin/useTradingWallet.ts +1 -1
  89. package/src/hooks/bitcoin/useTradingWalletBalance.ts +25 -14
  90. package/src/hooks/bridge/index.ts +5 -5
  91. package/src/hooks/bridge/useBridge.ts +29 -55
  92. package/src/hooks/bridge/useBridgeAllowance.ts +38 -38
  93. package/src/hooks/bridge/useBridgeApprove.ts +32 -57
  94. package/src/hooks/bridge/useGetBridgeableAmount.ts +23 -37
  95. package/src/hooks/bridge/useGetBridgeableTokens.ts +27 -50
  96. package/src/hooks/dex/index.ts +16 -16
  97. package/src/hooks/dex/useClaimRewards.ts +35 -54
  98. package/src/hooks/dex/useCreateDecreaseLiquidityParams.ts +7 -20
  99. package/src/hooks/dex/useCreateDepositParams.ts +7 -21
  100. package/src/hooks/dex/useCreateSupplyLiquidityParams.ts +13 -28
  101. package/src/hooks/dex/useCreateWithdrawParams.ts +7 -20
  102. package/src/hooks/dex/useDecreaseLiquidity.ts +40 -66
  103. package/src/hooks/dex/useDexAllowance.ts +29 -75
  104. package/src/hooks/dex/useDexApprove.ts +32 -43
  105. package/src/hooks/dex/useDexDeposit.ts +42 -49
  106. package/src/hooks/dex/useDexWithdraw.ts +32 -43
  107. package/src/hooks/dex/useLiquidityAmounts.ts +13 -82
  108. package/src/hooks/dex/usePoolBalances.ts +50 -72
  109. package/src/hooks/dex/usePoolData.ts +17 -43
  110. package/src/hooks/dex/usePools.ts +11 -38
  111. package/src/hooks/dex/usePositionInfo.ts +27 -62
  112. package/src/hooks/dex/useSupplyLiquidity.ts +80 -75
  113. package/src/hooks/index.ts +12 -10
  114. package/src/hooks/migrate/index.ts +13 -4
  115. package/src/hooks/migrate/useMigrateBaln.ts +42 -0
  116. package/src/hooks/migrate/useMigrateIcxToSoda.ts +44 -0
  117. package/src/hooks/migrate/useMigratebnUSD.ts +47 -0
  118. package/src/hooks/migrate/useMigrationAllowance.ts +76 -0
  119. package/src/hooks/migrate/useMigrationApprove.ts +66 -0
  120. package/src/hooks/migrate/useRevertMigrateSodaToIcx.ts +39 -0
  121. package/src/hooks/mm/index.ts +14 -12
  122. package/src/hooks/mm/useAToken.ts +25 -41
  123. package/src/hooks/mm/useATokensBalances.ts +29 -60
  124. package/src/hooks/mm/useBorrow.ts +38 -56
  125. package/src/hooks/mm/useMMAllowance.ts +37 -73
  126. package/src/hooks/mm/useMMApprove.ts +36 -43
  127. package/src/hooks/mm/useRepay.ts +33 -53
  128. package/src/hooks/mm/useReservesData.ts +12 -38
  129. package/src/hooks/mm/useReservesHumanized.ts +12 -31
  130. package/src/hooks/mm/useReservesList.ts +11 -31
  131. package/src/hooks/mm/useReservesUsdFormat.ts +15 -35
  132. package/src/hooks/mm/useSupply.ts +45 -51
  133. package/src/hooks/mm/useUserFormattedSummary.ts +32 -84
  134. package/src/hooks/mm/useUserReservesData.ts +27 -77
  135. package/src/hooks/mm/useWithdraw.ts +38 -54
  136. package/src/hooks/partner/index.ts +6 -0
  137. package/src/hooks/partner/useApproveToken.ts +42 -0
  138. package/src/hooks/partner/useFeeClaimSwap.ts +38 -0
  139. package/src/hooks/partner/useFetchAssetsBalances.ts +37 -0
  140. package/src/hooks/partner/useGetAutoSwapPreferences.ts +37 -0
  141. package/src/hooks/partner/useIsTokenApproved.ts +39 -0
  142. package/src/hooks/partner/useSetSwapPreference.ts +50 -0
  143. package/src/hooks/provider/index.ts +1 -2
  144. package/src/hooks/provider/useHubProvider.ts +1 -1
  145. package/src/hooks/recovery/index.ts +2 -0
  146. package/src/hooks/recovery/useHubAssetBalances.ts +43 -0
  147. package/src/hooks/recovery/useWithdrawHubAsset.ts +48 -0
  148. package/src/hooks/shared/index.ts +10 -6
  149. package/src/hooks/shared/types.ts +77 -0
  150. package/src/hooks/shared/unwrapResult.ts +19 -0
  151. package/src/hooks/shared/useDeriveUserWalletAddress.ts +22 -40
  152. package/src/hooks/shared/useEstimateGas.ts +18 -15
  153. package/src/hooks/shared/useGetUserHubWalletAddress.ts +25 -26
  154. package/src/hooks/shared/useRequestTrustline.ts +28 -61
  155. package/src/hooks/shared/useSafeMutation.test.ts +43 -0
  156. package/src/hooks/shared/useSafeMutation.ts +68 -0
  157. package/src/hooks/shared/useSodaxContext.ts +1 -1
  158. package/src/hooks/shared/useStellarTrustlineCheck.ts +30 -64
  159. package/src/hooks/shared/useXBalances.test.ts +113 -0
  160. package/src/hooks/shared/useXBalances.ts +61 -0
  161. package/src/hooks/staking/index.ts +18 -18
  162. package/src/hooks/staking/useCancelUnstake.ts +30 -41
  163. package/src/hooks/staking/useClaim.ts +27 -36
  164. package/src/hooks/staking/useConvertedAssets.ts +24 -34
  165. package/src/hooks/staking/useInstantUnstake.ts +33 -40
  166. package/src/hooks/staking/useInstantUnstakeAllowance.ts +37 -45
  167. package/src/hooks/staking/useInstantUnstakeApprove.ts +42 -42
  168. package/src/hooks/staking/useInstantUnstakeRatio.ts +24 -41
  169. package/src/hooks/staking/useStake.ts +32 -37
  170. package/src/hooks/staking/useStakeAllowance.ts +30 -43
  171. package/src/hooks/staking/useStakeApprove.ts +40 -40
  172. package/src/hooks/staking/useStakeRatio.ts +24 -40
  173. package/src/hooks/staking/useStakingConfig.ts +14 -27
  174. package/src/hooks/staking/useStakingInfo.ts +30 -38
  175. package/src/hooks/staking/useUnstake.ts +29 -43
  176. package/src/hooks/staking/useUnstakeAllowance.ts +37 -44
  177. package/src/hooks/staking/useUnstakeApprove.ts +40 -43
  178. package/src/hooks/staking/useUnstakingInfo.ts +29 -41
  179. package/src/hooks/staking/useUnstakingInfoWithPenalty.ts +31 -47
  180. package/src/hooks/swap/index.ts +8 -8
  181. package/src/hooks/swap/useCancelLimitOrder.ts +24 -41
  182. package/src/hooks/swap/useCancelSwap.ts +24 -33
  183. package/src/hooks/swap/useCreateLimitOrder.ts +29 -62
  184. package/src/hooks/swap/useQuote.ts +17 -43
  185. package/src/hooks/swap/useStatus.ts +22 -29
  186. package/src/hooks/swap/useSwap.ts +31 -49
  187. package/src/hooks/swap/useSwapAllowance.ts +38 -35
  188. package/src/hooks/swap/useSwapApprove.ts +48 -57
  189. package/src/index.ts +5 -3
  190. package/src/providers/SodaxProvider.tsx +17 -11
  191. package/src/providers/createSodaxQueryClient.ts +96 -0
  192. package/src/providers/index.ts +2 -1
  193. package/src/utils/dex-utils.ts +27 -5
  194. package/src/utils/index.ts +1 -1
  195. package/dist/index.d.mts +0 -2581
  196. package/dist/index.js +0 -2574
  197. package/dist/index.js.map +0 -1
  198. package/src/hooks/migrate/types.ts +0 -15
  199. package/src/hooks/migrate/useMigrate.tsx +0 -110
  200. package/src/hooks/migrate/useMigrationAllowance.tsx +0 -79
  201. package/src/hooks/migrate/useMigrationApprove.tsx +0 -129
  202. package/src/hooks/provider/useSpokeProvider.ts +0 -172
@@ -0,0 +1,211 @@
1
+ # Result<T> handling — v1 → v2
2
+
3
+ The most subtle breakage: `Result<T>` semantics inside dapp-kit's mutation pipeline inverted in v2.
4
+
5
+ ## The semantic shift
6
+
7
+ | | v1 | v2 |
8
+ |---|---|---|
9
+ | `mutationFn` return | `Result<T>` | unwrapped `T`; throws on `!ok` |
10
+ | `mutation.data` shape | `Result<T>` (`{ ok, value }` or `{ ok, error }`) | unwrapped `T` (e.g. `SwapResponse`, `TxHashPair`) |
11
+ | Where to branch | Inside `onSuccess`: `if (data.ok) ...` | Branch on `mutation.error` / `mutation.isError`, OR use `mutateAsyncSafe` |
12
+ | `onSuccess` fires on SDK `!ok`? | **Yes** (success path) — required `data.ok` check inside | **No** — only on actual success |
13
+ | `onError` fires on SDK `!ok`? | No | **Yes** — engages React Query's native error model |
14
+ | `retry` config | Ignored on SDK `!ok` | Engages on SDK `!ok` |
15
+ | Devtools error display | Empty | Shows the SDK error |
16
+
17
+ The shift makes React Query's native error model engage for SDK failures, instead of treating every SDK call as "successful but maybe with an error inside."
18
+
19
+ ## Why the change
20
+
21
+ In v1:
22
+ - Consumers had to remember to branch on `data.ok` inside every `onSuccess`. Forgetting was easy and silent (success logic ran on a failed swap).
23
+ - Hook-owned invalidations fired on SDK failure too, burning RPC traffic on every failed click.
24
+ - Devtools showed every mutation as "success" even when the SDK returned `{ ok: false }`.
25
+ - `retry` config didn't engage (the request didn't "fail" from React Query's perspective).
26
+
27
+ v2's `mutationFn` calls `unwrapResult(await sodax.<feature>.<method>(vars))`:
28
+ - `Result<T>` `{ ok: true; value }` → returns `value` (the unwrapped success type).
29
+ - `Result<T>` `{ ok: false; error }` → throws `error`.
30
+
31
+ This makes `isError`, `error`, `onError`, `retry`, devtools all work correctly out of the box.
32
+
33
+ ## Migration patterns
34
+
35
+ ### Pattern 1: success-path branching → drop the check
36
+
37
+ ```diff
38
+ const { mutateAsync: swap } = useSwap({
39
+ mutationOptions: {
40
+ - onSuccess: (data, vars) => {
41
+ - if (data.ok) {
42
+ - showSuccess(data.value.intent);
43
+ - } else {
44
+ - showError(data.error);
45
+ - }
46
+ - },
47
+ + onSuccess: (data, vars) => {
48
+ + // data is now SwapResponse — already-unwrapped success value.
49
+ + showSuccess(data.intent);
50
+ + },
51
+ + onError: (error) => {
52
+ + showError(error);
53
+ + },
54
+ },
55
+ });
56
+ ```
57
+
58
+ `onSuccess` only fires on actual success now; `onError` fires on SDK failure. Move the failure logic to `onError`.
59
+
60
+ ### Pattern 2: imperative `mutateAsync` → wrap in try/catch
61
+
62
+ ```diff
63
+ const { mutateAsync: swap } = useSwap();
64
+ - const result = await swap({ params, spokeProvider });
65
+ - if (result.ok) {
66
+ - navigate('/done');
67
+ - } else {
68
+ - toast.error(result.error.message);
69
+ - }
70
+ + try {
71
+ + const result = await swap({ params, walletProvider });
72
+ + navigate('/done');
73
+ + } catch (e) {
74
+ + toast.error(e instanceof Error ? e.message : 'Swap failed');
75
+ + }
76
+ ```
77
+
78
+ v2's `mutateAsync` rejects on SDK `!ok` — `try/catch` is mandatory. If you forget `try/catch`, an unhandled rejection lands in the global handler.
79
+
80
+ ### Pattern 3: imperative `mutateAsync` → use `mutateAsyncSafe` (recommended)
81
+
82
+ If you prefer the v1 `Result<T>` ergonomics without exception flow, use `mutateAsyncSafe` — it never rejects:
83
+
84
+ ```diff
85
+ - const { mutateAsync: swap } = useSwap();
86
+ - const result = await swap({ params, spokeProvider });
87
+ - if (result.ok) {
88
+ - navigate('/done');
89
+ - } else {
90
+ - toast.error(result.error.message);
91
+ - }
92
+ + const { mutateAsyncSafe: swap } = useSwap();
93
+ + const result = await swap({ params, walletProvider });
94
+ + if (!result.ok) {
95
+ + toast.error(result.error instanceof Error ? result.error.message : 'Swap failed');
96
+ + return;
97
+ + }
98
+ + navigate('/done');
99
+ ```
100
+
101
+ `mutateAsyncSafe` re-packs the throw inside `mutationFn` back into `Result<TData>`. Same React Query state under the hood (`isError`, `error`, devtools all work). Recommended for sequenced flows.
102
+
103
+ ### Pattern 4: sequenced flow (approve + execute)
104
+
105
+ ```diff
106
+ - // v1: branch on every step
107
+ - const result1 = await approve({ params, spokeProvider });
108
+ - if (!result1.ok) { toast(result1.error); return; }
109
+ - const result2 = await action({ params, spokeProvider });
110
+ - if (!result2.ok) { toast(result2.error); return; }
111
+ - navigate('/done');
112
+
113
+ + // v2: same shape, but Result is from mutateAsyncSafe; walletProvider in mutate(vars)
114
+ + const result1 = await approve({ params, walletProvider });
115
+ + if (!result1.ok) { toast(result1.error.message); return; }
116
+ + const result2 = await action({ params, walletProvider });
117
+ + if (!result2.ok) { toast(result2.error.message); return; }
118
+ + navigate('/done');
119
+ ```
120
+
121
+ Just swap `mutateAsync` → `mutateAsyncSafe` and `spokeProvider` → `walletProvider`. The branching pattern stays nearly identical — same `result.ok` check.
122
+
123
+ ## Edge case: `data` consumed in render
124
+
125
+ ```diff
126
+ function SwapResult() {
127
+ const { data, isError } = useSwap();
128
+ - if (data?.ok) return <p>Success: {data.value.intent.intentHash}</p>;
129
+ - if (data && !data.ok) return <p>Error: {data.error.message}</p>;
130
+ + const { data, error, isError } = useSwap();
131
+ + if (data) return <p>Success: {data.intent.intentHash}</p>;
132
+ + if (isError && error) return <p>Error: {error.message}</p>;
133
+ return null;
134
+ }
135
+ ```
136
+
137
+ `data` is the unwrapped success value or `undefined`. `error` is the SDK error (or `null`). `isError` is the React Query flag.
138
+
139
+ ## Edge case: `mutation.error` consumers
140
+
141
+ In v1, `mutation.error` only fired for actual exceptions (e.g. missing `walletProvider`, invalid input). In v2, it ALSO fires for SDK `!ok`. Audit all places that read `mutation.error` to ensure the new firings are appropriate.
142
+
143
+ ```ts
144
+ // @ai-snippets-skip
145
+ // v1: error was rare (only thrown exceptions)
146
+ {mutation.error && <p>Unexpected error: {mutation.error.message}</p>}
147
+
148
+ // v2: error includes SDK !ok
149
+ // You may want to distinguish, e.g. check isSodaxError(error)
150
+ {mutation.error && (
151
+ isSodaxError(mutation.error)
152
+ ? <p>SDK error ({mutation.error.code}): {mutation.error.message}</p>
153
+ : <p>Unexpected error: {mutation.error.message}</p>
154
+ )}
155
+ ```
156
+
157
+ `isSodaxError` is exported from `@sodax/dapp-kit` (re-exported from `@sodax/sdk`).
158
+
159
+ ## Edge case: query hooks returning `Result<T>` as data
160
+
161
+ A small set of query hooks for SDK methods that can fail in expected ways (e.g. quote unavailable, status not yet known) surface the `Result<T>` directly to the consumer as `data` rather than unwrapping. This is intentional — read failures are part of the data flow, not exception flow.
162
+
163
+ **Result-wrapped query hooks** (data is `Result<T> | undefined` — branch on `data?.ok`):
164
+
165
+ ```tsx
166
+ // @ai-snippets-skip
167
+ // useQuote — SDK request goes under params.payload
168
+ const { data: quoteResult } = useQuote({ params: { payload: quotePayload } });
169
+ if (quoteResult?.ok) {
170
+ const quote = quoteResult.value;
171
+ }
172
+
173
+ // useStatus — key is `intentTxHash`, NOT `intentHash`
174
+ const { data: statusResult } = useStatus({ params: { intentTxHash } });
175
+ if (statusResult?.ok) {
176
+ const status = statusResult.value;
177
+ }
178
+ ```
179
+
180
+ **Most other query hooks unwrap** the SDK Result inside the hook (`if (!result.ok) throw result.error`), so `data` is the success value directly and React Query's native error model (`isError`/`error`/`onError`/`retry`) engages on SDK failure. Examples:
181
+
182
+ ```tsx
183
+ // @ai-snippets-skip
184
+ // useStakingInfo, useUnstakingInfo, useUnstakingInfoWithPenalty,
185
+ // useStakingConfig, useStakeRatio, useInstantUnstakeRatio, useConvertedAssets,
186
+ // all three staking allowance hooks (useStakeAllowance/useUnstakeAllowance/useInstantUnstakeAllowance),
187
+ // useMMAllowance, useSwapAllowance, useDexAllowance,
188
+ // all MM reserves + position hooks, all DEX read hooks except where noted —
189
+ // data is the unwrapped value. NO `.ok` / `.value` branching.
190
+ const { data: info, isError, error } = useStakingInfo({ params: { srcAddress, srcChainKey } });
191
+ // info is StakingInfo | undefined — read fields directly: info?.totalStaked
192
+ ```
193
+
194
+ **`useBridgeAllowance` is special** — it returns `false` on SDK `!ok` (does NOT throw). The data is still `boolean | undefined`, just biased toward "not approved" on lookup error.
195
+
196
+ For per-hook truth, check the per-feature reference (`integration/features/<x>.md`).
197
+
198
+ ## Done criteria for this category
199
+
200
+ - [ ] No `data.ok` checks inside mutation `onSuccess` callbacks.
201
+ - [ ] No `result.ok` branching after `mutateAsync(...)` (it now throws — either `try/catch` or use `mutateAsyncSafe`).
202
+ - [ ] All `mutateAsync` calls are wrapped in `try/catch` OR replaced with `mutateAsyncSafe`.
203
+ - [ ] `onError` callbacks audit — they now fire for SDK `!ok` (which they didn't before).
204
+ - [ ] Mutation `mutation.error` reads — same audit.
205
+
206
+ ## Cross-references
207
+
208
+ - [`hook-signatures.md`](hook-signatures.md) — the structural changes (provider stack, hook shapes, approve returns).
209
+ - [`../../integration/recipes/mutation-error-handling.md`](../../integration/recipes/mutation-error-handling.md) — full v2 patterns for picking call shapes.
210
+ - [`../../integration/architecture.md`](../../integration/architecture.md) § "SDK Result handling" — full design rationale.
211
+ - [`../../../../sdk/ai-exported/migration/breaking-changes/result-and-errors.md`](../../../../sdk/ai-exported/migration/breaking-changes/result-and-errors.md) — SDK-side `Result<T>` migration (the underlying contract that dapp-kit translates).
@@ -0,0 +1,165 @@
1
+ # SDK leakage — v1 → v2
2
+
3
+ Some v1 dapp-kit migration items are really *SDK* migrations that surface through dapp-kit's hook signatures. Each is documented in detail in the SDK's migration tree — this file summarizes what you'll see at the dapp-kit layer and links out for the full picture.
4
+
5
+ ## chain-key terminology
6
+
7
+ The SDK renamed `xChainId` / `srcChainId` / `dstChainId` to `chainKey` / `srcChainKey` / `dstChainKey` on token shapes and request params. In dapp-kit, this surfaces in:
8
+
9
+ ```diff
10
+ - // useGetBridgeableTokens — v1 took chain ids
11
+ - useGetBridgeableTokens(BASE_MAINNET_CHAIN_ID, POLYGON_MAINNET_CHAIN_ID, '0x...');
12
+ + // v2 takes chain keys via the canonical query shape
13
+ + useGetBridgeableTokens({ params: { from: ChainKeys.BASE_MAINNET, to: ChainKeys.POLYGON_MAINNET, token: '0x...' } });
14
+ ```
15
+
16
+ ```diff
17
+ - // bridge params — v1
18
+ - await bridge({ params: { srcChainId: BASE_MAINNET_CHAIN_ID, dstChainId: POLYGON_MAINNET_CHAIN_ID, /* ... */ } });
19
+ + // v2
20
+ + await bridge({ params: { srcChainKey: ChainKeys.BASE_MAINNET, dstChainKey: ChainKeys.POLYGON_MAINNET, /* ... */ }, walletProvider });
21
+ ```
22
+
23
+ ```diff
24
+ - // XToken read shape — v1
25
+ - const chainId = token.xChainId;
26
+ + // v2
27
+ + const chainKey = token.chainKey;
28
+ ```
29
+
30
+ **Note:** `useXBalances` request params still take `xChainId` (the field name stayed for the cross-chain abstraction it overlays). This is distinct from the renamed token-side `chainKey`. Don't conflate them.
31
+
32
+ **Note:** `Intent.srcChain` / `Intent.dstChain` (read shape) kept their names. They're `IntentRelayChainId` (bigints), distinct from request-side `srcChainKey` / `dstChainKey`. Don't blanket grep-replace.
33
+
34
+ Full SDK-level detail: [`../../../../sdk/ai-exported/migration/breaking-changes/type-system.md`](../../../../sdk/ai-exported/migration/breaking-changes/type-system.md).
35
+
36
+ ## Required `srcChainKey` + `srcAddress` on action params
37
+
38
+ v1 mutation params were minimal (`{ token, amount, action }`). v2 added required `srcChainKey` + `srcAddress` to every feature's action params. The chain key drives spoke routing internally; the address is the user's spoke-side address.
39
+
40
+ ```diff
41
+ - // v1
42
+ - await supply({ params: { token, amount, action: 'supply' } });
43
+ + // v2
44
+ + await supply({
45
+ + params: {
46
+ + srcChainKey: ChainKeys.BASE_MAINNET,
47
+ + srcAddress: '0x...', // NEW: required
48
+ + token,
49
+ + amount,
50
+ + action: 'supply',
51
+ + },
52
+ + walletProvider,
53
+ + });
54
+ ```
55
+
56
+ Same applies to `useBorrow`, `useWithdraw`, `useRepay`, `useStake`, `useUnstake`, `useBridge`, `useDexDeposit`, `useDexWithdraw`, etc. — anywhere the SDK now requires it.
57
+
58
+ Full SDK-level detail: [`../../../../sdk/ai-exported/migration/features/`](../../../../sdk/ai-exported/migration/features/) — each feature's migration file lists the required new fields.
59
+
60
+ ## `*_MAINNET_CHAIN_ID` constants gone
61
+
62
+ v1 exported individual constants (`BSC_MAINNET_CHAIN_ID`, `BASE_MAINNET_CHAIN_ID`, etc.). v2 replaces them with the `ChainKeys.*` namespace.
63
+
64
+ ```diff
65
+ - import { BSC_MAINNET_CHAIN_ID, BASE_MAINNET_CHAIN_ID } from '@sodax/sdk';
66
+ + import { ChainKeys } from '@sodax/sdk';
67
+
68
+ - const chainKey = BSC_MAINNET_CHAIN_ID;
69
+ + const chainKey = ChainKeys.BSC_MAINNET;
70
+ ```
71
+
72
+ Codemod with sed:
73
+
74
+ ```bash
75
+ find src -type f \( -name '*.ts' -o -name '*.tsx' \) | xargs sed -i '' -E 's/\b([A-Z_]+)_MAINNET_CHAIN_ID\b/ChainKeys.\1_MAINNET/g'
76
+ ```
77
+
78
+ Then add `import { ChainKeys } from '@sodax/sdk'` (or `@sodax/dapp-kit`) where needed.
79
+
80
+ Full SDK-level detail: [`../../../../sdk/ai-exported/migration/breaking-changes/type-system.md`](../../../../sdk/ai-exported/migration/breaking-changes/type-system.md).
81
+
82
+ ## `SodaxConfig` reshape — `rpcConfig` → `chains`
83
+
84
+ `SodaxProvider`'s config prop is `DeepPartial<SodaxConfig>`. The SDK renamed/restructured the config:
85
+
86
+ ```diff
87
+ - <SodaxProvider rpcConfig={{
88
+ - sonic: 'https://sonic-rpc.publicnode.com',
89
+ - '0xa86a.avax': 'https://...',
90
+ - }}>
91
+ + <SodaxProvider config={{
92
+ + chains: {
93
+ + [ChainKeys.SONIC_MAINNET]: { rpcUrl: 'https://sonic-rpc.publicnode.com' },
94
+ + [ChainKeys.AVALANCHE_MAINNET]: { rpcUrl: 'https://...' },
95
+ + },
96
+ + }}>
97
+ ```
98
+
99
+ Other v1 fields renamed or restructured:
100
+
101
+ | v1 | v2 |
102
+ |---|---|
103
+ | `rpcConfig` | `chains[ChainKeys.X]: { rpcUrl }` |
104
+ | `backendApi: { url }` | `api: { baseURL }` |
105
+ | `swaps: { intentsContract, ... }` | Split: `solver: { intentsContract, ... }` for endpoints; `swaps: SwapsConfig` for supported tokens |
106
+ | `hubProviderConfig` | `hub: HubConfig` |
107
+
108
+ Full SDK-level detail: [`../../../../sdk/ai-exported/migration/breaking-changes/architecture.md`](../../../../sdk/ai-exported/migration/breaking-changes/architecture.md) (Appendix B).
109
+
110
+ ## Error class
111
+
112
+ The SDK consolidated 7+ per-feature error classes (`MoneyMarketError<Code>`, `IntentError<Code>`, `StakingError<Code>`, `BridgeError<Code>`, `MigrationError<Code>`, etc.) into a single canonical `SodaxError<C>`.
113
+
114
+ If your dapp-kit consumer code catches errors from mutations and uses `instanceof XxxError`, those checks are now broken:
115
+
116
+ ```diff
117
+ - // v1
118
+ - catch (e) {
119
+ - if (e instanceof MoneyMarketError) {
120
+ - console.error('MM-specific:', e.code);
121
+ - }
122
+ - }
123
+
124
+ + // v2
125
+ + catch (e) {
126
+ + if (isSodaxError(e) && e.feature === 'moneyMarket') {
127
+ + console.error('MM-specific:', e.code);
128
+ + }
129
+ + }
130
+ ```
131
+
132
+ `isSodaxError` is re-exported from `@sodax/dapp-kit`. Discriminate via `(error.feature, error.code)` — the feature is now a first-class field, and the code vocabulary is unified to 13 reason-only codes.
133
+
134
+ Full SDK-level detail: [`../../../../sdk/ai-exported/migration/breaking-changes/result-and-errors.md`](../../../../sdk/ai-exported/migration/breaking-changes/result-and-errors.md).
135
+
136
+ ## `Result<T>` type and propagation
137
+
138
+ The SDK's `Result<T>` type is the same in v1 and v2. What changed is **where it's returned vs unwrapped**:
139
+
140
+ | | v1 | v2 |
141
+ |---|---|---|
142
+ | SDK service method return | `Result<T>` | `Result<T>` (unchanged) |
143
+ | dapp-kit `mutationFn` return | `Result<T>` | unwrapped `T` (throws on `!ok`) |
144
+ | Consumer's `mutation.data` | `Result<T>` | unwrapped `T` |
145
+
146
+ So at the SDK level, `Result<T>` semantics didn't change. But at the dapp-kit level, the unwrap point moved into the hook. See [`result-handling.md`](result-handling.md) for the full picture.
147
+
148
+ ## Other SDK-level migrations
149
+
150
+ These are unlikely to leak through hook signatures unless your app reaches into the SDK directly via `useSodaxContext()`:
151
+
152
+ - **`*SpokeProvider` classes deleted** — the chain key drives spoke routing; no provider classes to construct. dapp-kit consumers never see these (you'd already be using `useSpokeProvider` which is gone).
153
+ - **`ConfigService` replaces static lookup tables** — `hubAssets`, `moneyMarketSupportedTokens`, `SodaTokens` globals are gone. Use `sodax.config.*` (which dapp-kit's hooks already do internally).
154
+ - **`WalletProviderSlot<K, Raw>` discriminated union** — a TypeScript-level construct; `walletProvider` is the typical consumer-facing shape.
155
+
156
+ For the full SDK migration playbook, start at [`../../../../sdk/ai-exported/migration/README.md`](../../../../sdk/ai-exported/migration/README.md).
157
+
158
+ ## Cross-references
159
+
160
+ - [`../../../../sdk/ai-exported/migration/README.md`](../../../../sdk/ai-exported/migration/README.md) — full SDK migration overview.
161
+ - [`../../../../sdk/ai-exported/migration/breaking-changes/type-system.md`](../../../../sdk/ai-exported/migration/breaking-changes/type-system.md) — type renames + ChainKeys.
162
+ - [`../../../../sdk/ai-exported/migration/breaking-changes/architecture.md`](../../../../sdk/ai-exported/migration/breaking-changes/architecture.md) — `*SpokeProvider`, ConfigService, SodaxConfig reshape.
163
+ - [`../../../../sdk/ai-exported/migration/breaking-changes/result-and-errors.md`](../../../../sdk/ai-exported/migration/breaking-changes/result-and-errors.md) — `Result<T>` + error class consolidation.
164
+ - [`hook-signatures.md`](hook-signatures.md) — dapp-kit-only hook-shape changes.
165
+ - [`result-handling.md`](result-handling.md) — dapp-kit-only `Result<T>` unwrap-point shift.
@@ -0,0 +1,89 @@
1
+ # Migration checklist — `@sodax/dapp-kit` v1 → v2
2
+
3
+ Top-down cross-cutting checklist. Walk it in order — each step makes later ones tractable.
4
+
5
+ ## Phase 1 — provider stack and imports
6
+
7
+ - [ ] **Update `SodaxProvider` config shape.** `rpcConfig: { sonic: '...', ... }` → `chains: { [ChainKeys.SONIC_MAINNET]: { rpcUrl: '...' } }`. See [`breaking-changes/hook-signatures.md`](breaking-changes/hook-signatures.md) § Provider stack.
8
+ - [ ] **Replace `new QueryClient()` with `createSodaxQueryClient()`** (optional but recommended — gives you global mutation observability).
9
+ - [ ] **Drop any `@sodax/types` dependency** from `package.json`. Re-exported via `@sodax/sdk` (which dapp-kit re-exports). Run `pnpm install` after.
10
+ - [ ] **Import statement codemod.**
11
+ - `useSpokeProvider` import → delete the import line.
12
+ - `BSC_MAINNET_CHAIN_ID` (and the 14 other `*_MAINNET_CHAIN_ID` constants) → `ChainKeys.X_MAINNET`.
13
+ - Any deep-import from `@sodax/dapp-kit/dist/...` → import from `@sodax/dapp-kit` root.
14
+
15
+ ## Phase 2 — mechanical sweeps
16
+
17
+ - [ ] **Delete every `useSpokeProvider(...)` call.** The `walletProvider` from `useWalletProvider({ xChainId: chainKey })` flows directly into `mutate(vars)`. See [`reference/deleted-hooks.md`](reference/deleted-hooks.md).
18
+ - [ ] **`*_MAINNET_CHAIN_ID` → `ChainKeys.X_MAINNET`.** Codemod with sed:
19
+
20
+ ```bash
21
+ find src -type f \( -name '*.ts' -o -name '*.tsx' \) | xargs sed -i '' -E 's/\b([A-Z_]+)_MAINNET_CHAIN_ID\b/ChainKeys.\1_MAINNET/g'
22
+ ```
23
+
24
+ - [ ] **`xChainId` → `chainKey` on `XToken`.** Be careful — only on the read shape. The `useXBalances` hook still takes `xChainId` as a request param (intentional naming for the cross-chain abstraction). See [`breaking-changes/sdk-leakage.md`](breaking-changes/sdk-leakage.md).
25
+
26
+ ## Phase 3 — hook-call-site rewrites (per feature)
27
+
28
+ For each feature your app uses, walk the matching `migration/features/<feature>.md`:
29
+
30
+ - [ ] [`features/swap.md`](features/swap.md) — swap call sites.
31
+ - [ ] [`features/money-market.md`](features/money-market.md) — supply / borrow / withdraw / repay.
32
+ - [ ] [`features/staking.md`](features/staking.md) — stake / unstake / claim.
33
+ - [ ] [`features/bridge.md`](features/bridge.md) — bridge.
34
+ - [ ] [`features/dex.md`](features/dex.md) — deposit / supply liquidity / etc.
35
+ - [ ] [`features/migration.md`](features/migration.md) — ICX / bnUSD / BALN. **Note:** v1's `useMigrate(spokeProvider)` is gone; v2 has 6 per-action hooks.
36
+ - [ ] [`features/bitcoin.md`](features/bitcoin.md) — Radfi.
37
+ - [ ] [`features/auxiliary-services.md`](features/auxiliary-services.md) — partner, recovery, backend queries, shared utilities.
38
+
39
+ The cross-cutting pattern at every call site:
40
+
41
+ 1. **Hook init**: `useFoo(spokeProvider, params)` → `useFoo()` or `useFoo({ mutationOptions })`. No domain inputs at hook init.
42
+ 2. **Mutation invocation**: `mutate(spokeProvider)` or `mutate()` → `mutate({ params, walletProvider })`. ALL domain inputs flow through here.
43
+ 3. **Approve hooks**: `const { approve, isLoading } = useFooApprove(spokeProvider)` → `const { mutateAsync: approve, isPending } = useFooApprove()`.
44
+ 4. **Query hooks**: `useFoo(arg1, arg2)` → `useFoo({ params: { ... }, queryOptions: { ... } })`.
45
+
46
+ ## Phase 4 — Result<T> handling
47
+
48
+ - [ ] **Mutation success-path branching.** v1: `onSuccess: (data) => { if (data.ok) ... }`. v2: drop the `.ok` check; `data` is unwrapped success (e.g. `SwapResponse`, `TxHashPair`).
49
+ - [ ] **Convert imperative `mutateAsync` calls.** Wrap in `try/catch` (v2 throws on `!ok`) OR switch to `mutateAsyncSafe` and branch on `result.ok`. See [`breaking-changes/result-handling.md`](breaking-changes/result-handling.md).
50
+ - [ ] **Audit `onError` callbacks.** They now fire for SDK `!ok` (didn't in v1). Check that any error-toast logic is appropriate.
51
+
52
+ ## Phase 5 — invalidations
53
+
54
+ - [ ] **Delete `invalidate*Queries` utility files.** Hook-owned in v2; no consumer-side invalidation needed.
55
+ - [ ] **Drop manual `queryClient.invalidateQueries(...)` calls** that mirror what dapp-kit hooks already do (e.g. `xBalances` after a swap).
56
+ - [ ] **Keep ONLY the cross-feature invalidations** that dapp-kit hooks don't know about (e.g. your custom analytics view query).
57
+ - [ ] **If you have consumer wrappers around dapp-kit mutations**, ensure they don't double-invalidate. Move custom invalidations to the wrapper's `mutationOptions.onSuccess`.
58
+
59
+ ## Phase 6 — queryKey alignment (optional but recommended)
60
+
61
+ If your code grafts onto dapp-kit's cache invalidation (e.g. you fetch a related query and want it to be invalidated by dapp-kit's mutation), align your queryKeys with dapp-kit conventions:
62
+
63
+ - [ ] **First segment = feature directory name.** `'swap'`, `'mm'`, `'bridge'`, etc. See [`../integration/reference/querykey-conventions.md`](../integration/reference/querykey-conventions.md).
64
+ - [ ] **camelCase segments.** No kebab-case.
65
+ - [ ] **Bigints stringified** in keys.
66
+
67
+ ## Phase 7 — SDK-level migrations leaking through
68
+
69
+ These are SDK-level changes that surface in dapp-kit hook signatures or types. Refer to the SDK migration tree for full detail:
70
+
71
+ - [ ] **Chain-key terminology** — `xChainId` / `srcChainId` / `dstChainId` on action params → `chainKey` / `srcChainKey` / `dstChainKey`. See [`../../../sdk/ai-exported/migration/breaking-changes/type-system.md`](../../../sdk/ai-exported/migration/breaking-changes/type-system.md).
72
+ - [ ] **SodaxConfig reshape** — flat `rpcConfig` → nested `chains[ChainKeys.X]: { rpcUrl }`. See [`../../../sdk/ai-exported/migration/breaking-changes/architecture.md`](../../../sdk/ai-exported/migration/breaking-changes/architecture.md).
73
+ - [ ] **Error class** — `MoneyMarketError<Code>` etc. → single `SodaxError<C>`. See [`../../../sdk/ai-exported/migration/breaking-changes/result-and-errors.md`](../../../sdk/ai-exported/migration/breaking-changes/result-and-errors.md). dapp-kit consumers see this only if they directly reference SDK error classes.
74
+
75
+ ## Phase 8 — verification
76
+
77
+ - [ ] `pnpm tsc --noEmit` is clean.
78
+ - [ ] Smoke-test each feature your app uses: connect wallet, run one mutation, observe success + state updates.
79
+ - [ ] Search for v1 leftovers: `grep -rE '\buseSpokeProvider\b|\binvalidateMmQueries\b|_MAINNET_CHAIN_ID\b'` returns zero hits.
80
+ - [ ] Confirm `mutateAsync` calls are wrapped in `try/catch` OR replaced with `mutateAsyncSafe`.
81
+ - [ ] Confirm provider stack uses `chains: ...` not `rpcConfig: ...`.
82
+
83
+ ## Cross-references
84
+
85
+ - [`README.md`](README.md) — overview and v1↔v2 glossary.
86
+ - [`ai-rules.md`](ai-rules.md) — DO / DO NOT for the agent doing the migration.
87
+ - [`breaking-changes/`](breaking-changes/) — cross-cutting v1→v2 deltas (hook signatures, result handling, queryKey, SDK leakage).
88
+ - [`recipes.md`](recipes.md) — codemods and adapters.
89
+ - [`features/`](features/) — per-feature porting playbooks.
@@ -0,0 +1,34 @@
1
+ # Migration features — `@sodax/dapp-kit` v1 → v2
2
+
3
+ Per-feature porting playbooks. Each file shows the v1 → v2 delta for one feature's hook surface, with concrete code diffs.
4
+
5
+ | File | What's covered |
6
+ |---|---|
7
+ | [`swap.md`](swap.md) | v1 `useSwap(spokeProvider)`-style call sites → v2 `mutate({ params, walletProvider })`. Approve return shape change. Result handling. |
8
+ | [`money-market.md`](money-market.md) | v1 supply/borrow/withdraw/repay → v2 same with `srcChainKey`/`srcAddress` required. Allowance auto-skip for borrow/withdraw. |
9
+ | [`staking.md`](staking.md) | All five mutations + their dedicated approve hooks. `useStakeRatio` returns a tuple in v2. |
10
+ | [`bridge.md`](bridge.md) | Field renames in `useBridge` params (`srcChainId` → `srcChainKey`, `recipient` → `dstAddress`). `useGetBridgeableAmount` shape change. |
11
+ | [`dex.md`](dex.md) | Two-step flow stayed the same; field renames + `srcChainKey` requirement. `useSupplyLiquidity` mint/increase routing. |
12
+ | [`migration.md`](migration.md) | **Biggest change**: v1's `useMigrate(spokeProvider)` → 6 per-action hooks. |
13
+ | [`bitcoin.md`](bitcoin.md) | Radfi flow shapes are mostly unchanged; provider/session lifecycle hooks tightened. |
14
+ | [`auxiliary-services.md`](auxiliary-services.md) | Partner / recovery / backend queries / shared utilities — small per-hook changes. |
15
+
16
+ ## Pair-completeness
17
+
18
+ Every file in this directory has a sibling in [`../../integration/features/`](../../integration/features/) with the same filename — the v2 design context for that feature. When you're stuck in one, the other is one path-swap away.
19
+
20
+ ## Cross-cutting prerequisites
21
+
22
+ Before reading a feature playbook, make sure you've already read the cross-cutting deltas:
23
+
24
+ - [`../breaking-changes/hook-signatures.md`](../breaking-changes/hook-signatures.md) — provider stack, hook init shapes, approve return.
25
+ - [`../breaking-changes/result-handling.md`](../breaking-changes/result-handling.md) — `Result<T>` semantic shift.
26
+ - [`../breaking-changes/sdk-leakage.md`](../breaking-changes/sdk-leakage.md) — `srcChainKey`/`srcAddress` required, chain-key terminology, etc.
27
+
28
+ The per-feature files below are about the *feature-specific* delta on top of those cross-cutting changes.
29
+
30
+ ## Cross-references
31
+
32
+ - [`../README.md`](../README.md) — migration overview + glossary.
33
+ - [`../checklist.md`](../checklist.md) — top-down checklist.
34
+ - [`../ai-rules.md`](../ai-rules.md) — DO / DO NOT for the porting agent.
@@ -0,0 +1,114 @@
1
+ # Auxiliary services migration — v1 → v2 (dapp-kit)
2
+
3
+ Pair: [`../../integration/features/auxiliary-services.md`](../../integration/features/auxiliary-services.md).
4
+
5
+ Smaller surfaces grouped together: partner, recovery, backend queries, shared utilities. Most changes are mechanical — single-object params, mutateAsyncSafe — same as the other features.
6
+
7
+ ## Partner (6 hooks)
8
+
9
+ ```diff
10
+ - const claim = useFeeClaimSwap(spokeProvider);
11
+ - await claim.mutateAsync(params);
12
+ + const walletProvider = useWalletProvider({ xChainId: ChainKeys.SONIC_MAINNET });
13
+ + const { mutateAsyncSafe: claim } = useFeeClaimSwap();
14
+ + const result = await claim({ params, walletProvider });
15
+ ```
16
+
17
+ `useApproveToken`, `useSetSwapPreference` — same pattern.
18
+
19
+ `useFetchAssetsBalances`, `useGetAutoSwapPreferences`, `useIsTokenApproved` — convert to single-object query shape.
20
+
21
+ ## Recovery (2 hooks)
22
+
23
+ ```diff
24
+ - const withdraw = useWithdrawHubAsset(spokeProvider);
25
+ + const { mutateAsyncSafe: withdraw } = useWithdrawHubAsset();
26
+ + await withdraw({ params, walletProvider });
27
+ ```
28
+
29
+ ## Backend queries (~13 hooks)
30
+
31
+ Read-only. No `walletProvider` involved. Convert to single-object query shape.
32
+
33
+ ```diff
34
+ - const { data: intent } = useBackendIntentByTxHash(txHash);
35
+ + const { data: intent } = useBackendIntentByTxHash({ params: { txHash } });
36
+
37
+ - const { data: orderbook } = useBackendOrderbook({ offset: '0', limit: '20' });
38
+ + const { data: orderbook } = useBackendOrderbook({ pagination: { offset: '0', limit: '20' } });
39
+
40
+ - const { data: position } = useBackendMoneyMarketPosition(userAddress);
41
+ + const { data: position } = useBackendMoneyMarketPosition({ params: { userAddress } });
42
+
43
+ - const { data: assets } = useBackendAllMoneyMarketAssets();
44
+ + const { data: assets } = useBackendAllMoneyMarketAssets({});
45
+ ```
46
+
47
+ `useBackendSubmitSwapTx` is a mutation — per-call config flows through `mutate(vars)`:
48
+
49
+ ```diff
50
+ - const submit = useBackendSubmitSwapTx({ baseURL: 'https://...' }); // v1: per-instance config
51
+ - await submit.mutateAsync(swapPayload);
52
+ + const { mutateAsync: submit } = useBackendSubmitSwapTx();
53
+ + await submit({ request: swapPayload, apiConfig: { baseURL: 'https://...' } }); // v2: per-call config
54
+ ```
55
+
56
+ ## Shared utilities
57
+
58
+ ### `useXBalances`
59
+
60
+ v2 requires four fields under `params`: `xService` (from `@sodax/wallet-sdk-react`), `xChainId`, `xTokens`, and `address`. The token list is no longer optional.
61
+
62
+ ```diff
63
+ - const { data: balances } = useXBalances(BSC_MAINNET_CHAIN_ID, address, tokens);
64
+ + import { useXService, getXChainType } from '@sodax/wallet-sdk-react';
65
+ + const xChainId = ChainKeys.BSC_MAINNET;
66
+ + const xService = useXService({ xChainType: getXChainType(xChainId) });
67
+ + const { data: balances } = useXBalances({
68
+ + params: { xService, xChainId, xTokens, address },
69
+ + });
70
+ ```
71
+
72
+ Note: the request param is still `xChainId` (not renamed to `chainKey`). This is intentional — `xChainId` overlays the cross-chain abstraction; the rename only happened for token-side fields. Don't conflate.
73
+
74
+ ### `useEstimateGas`
75
+
76
+ ```diff
77
+ - const estimate = useEstimateGas(walletProvider);
78
+ - await estimate.mutateAsync({ rawTx });
79
+ + const { mutateAsyncSafe: estimateGas } = useEstimateGas();
80
+ + const result = await estimateGas({ rawTx, walletProvider });
81
+ ```
82
+
83
+ ### `useStellarTrustlineCheck` / `useRequestTrustline`
84
+
85
+ ```diff
86
+ - const { data: hasTrustline } = useStellarTrustlineCheck(account, asset);
87
+ + const { data: hasTrustline } = useStellarTrustlineCheck({ params: { account, asset } });
88
+
89
+ - const request = useRequestTrustline(walletProvider);
90
+ - await request.mutateAsync({ account, asset });
91
+ + const { mutateAsync: request } = useRequestTrustline();
92
+ + await request({ account, asset, walletProvider });
93
+ ```
94
+
95
+ ### `useDeriveUserWalletAddress` / `useGetUserHubWalletAddress`
96
+
97
+ ```diff
98
+ - const { data: hubAddress } = useDeriveUserWalletAddress(spokeChainKey, srcAddress);
99
+ + const { data: hubAddress } = useDeriveUserWalletAddress({ params: { spokeChainKey, srcAddress } });
100
+ ```
101
+
102
+ ## Pitfalls
103
+
104
+ 1. **`useBackendIntentByTxHash` polls every 1s while pending** — same as v1, but make sure your `queryOptions.refetchInterval` overrides if needed.
105
+ 2. **`useBackendOrderbook` does NOT auto-refetch** — it has `staleTime: 30s` only, so data stays fresh for 30s after a fetch but won't refresh on its own. Trigger a refetch manually or pass `refetchInterval` via `queryOptions` if you need polling.
106
+ 3. **`useXBalances` uses `xChainId` (not `chainKey`)** — request-side field name retained on this hook.
107
+ 4. **`useBackendSubmitSwapTx` config moved to per-call.** v1 may have had `baseURL` at hook init; v2 puts it in `mutate(vars).apiConfig`. Lets you have a single hook serve multiple backends if needed.
108
+
109
+ ## Cross-references
110
+
111
+ - [`../../integration/features/auxiliary-services.md`](../../integration/features/auxiliary-services.md) — v2 reference.
112
+ - [`../../integration/recipes/backend-queries.md`](../../integration/recipes/backend-queries.md) — backend hooks worked examples.
113
+ - [`../../integration/recipes/wallet-connectivity.md`](../../integration/recipes/wallet-connectivity.md) — `useXBalances` worked example.
114
+ - [`../../../../sdk/ai-exported/migration/features/auxiliary-services.md`](../../../../sdk/ai-exported/migration/features/auxiliary-services.md) — underlying SDK auxiliary migrations.