@sodax/dapp-kit 2.0.0-rc.2 → 2.0.0-rc.4

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 (63) hide show
  1. package/README.md +9 -63
  2. package/dist/index.d.ts +11 -4
  3. package/dist/index.mjs +3 -6
  4. package/package.json +31 -19
  5. package/src/providers/SodaxProvider.tsx +15 -11
  6. package/ai-exported/AGENTS.md +0 -134
  7. package/ai-exported/integration/README.md +0 -49
  8. package/ai-exported/integration/ai-rules.md +0 -79
  9. package/ai-exported/integration/architecture.md +0 -274
  10. package/ai-exported/integration/features/README.md +0 -29
  11. package/ai-exported/integration/features/auxiliary-services.md +0 -169
  12. package/ai-exported/integration/features/bitcoin.md +0 -87
  13. package/ai-exported/integration/features/bridge.md +0 -91
  14. package/ai-exported/integration/features/dex.md +0 -152
  15. package/ai-exported/integration/features/migration.md +0 -118
  16. package/ai-exported/integration/features/money-market.md +0 -116
  17. package/ai-exported/integration/features/staking.md +0 -123
  18. package/ai-exported/integration/features/swap.md +0 -101
  19. package/ai-exported/integration/quickstart.md +0 -187
  20. package/ai-exported/integration/recipes/README.md +0 -136
  21. package/ai-exported/integration/recipes/backend-queries.md +0 -157
  22. package/ai-exported/integration/recipes/bitcoin.md +0 -193
  23. package/ai-exported/integration/recipes/bridge.md +0 -174
  24. package/ai-exported/integration/recipes/dex.md +0 -204
  25. package/ai-exported/integration/recipes/invalidations.md +0 -115
  26. package/ai-exported/integration/recipes/migration.md +0 -212
  27. package/ai-exported/integration/recipes/money-market.md +0 -206
  28. package/ai-exported/integration/recipes/mutation-error-handling.md +0 -118
  29. package/ai-exported/integration/recipes/observability.md +0 -93
  30. package/ai-exported/integration/recipes/setup.md +0 -144
  31. package/ai-exported/integration/recipes/staking.md +0 -202
  32. package/ai-exported/integration/recipes/swap.md +0 -272
  33. package/ai-exported/integration/recipes/wallet-connectivity.md +0 -101
  34. package/ai-exported/integration/reference/README.md +0 -12
  35. package/ai-exported/integration/reference/glossary.md +0 -188
  36. package/ai-exported/integration/reference/hooks-index.md +0 -190
  37. package/ai-exported/integration/reference/public-api.md +0 -110
  38. package/ai-exported/integration/reference/querykey-conventions.md +0 -179
  39. package/ai-exported/migration/README.md +0 -60
  40. package/ai-exported/migration/ai-rules.md +0 -81
  41. package/ai-exported/migration/breaking-changes/hook-signatures.md +0 -233
  42. package/ai-exported/migration/breaking-changes/querykey-conventions.md +0 -108
  43. package/ai-exported/migration/breaking-changes/result-handling.md +0 -211
  44. package/ai-exported/migration/breaking-changes/sdk-leakage.md +0 -165
  45. package/ai-exported/migration/checklist.md +0 -89
  46. package/ai-exported/migration/features/README.md +0 -34
  47. package/ai-exported/migration/features/auxiliary-services.md +0 -114
  48. package/ai-exported/migration/features/bitcoin.md +0 -88
  49. package/ai-exported/migration/features/bridge.md +0 -123
  50. package/ai-exported/migration/features/dex.md +0 -101
  51. package/ai-exported/migration/features/migration.md +0 -120
  52. package/ai-exported/migration/features/money-market.md +0 -97
  53. package/ai-exported/migration/features/staking.md +0 -109
  54. package/ai-exported/migration/features/swap.md +0 -118
  55. package/ai-exported/migration/recipes.md +0 -188
  56. package/ai-exported/migration/reference/README.md +0 -15
  57. package/ai-exported/migration/reference/deleted-hooks.md +0 -110
  58. package/ai-exported/migration/reference/error-shape-crosswalk.md +0 -144
  59. package/ai-exported/migration/reference/renamed-hooks.md +0 -66
  60. package/dist/index.cjs +0 -2642
  61. package/dist/index.cjs.map +0 -1
  62. package/dist/index.d.cts +0 -1550
  63. package/dist/index.mjs.map +0 -1
@@ -1,108 +0,0 @@
1
- # queryKey conventions — v1 → v2
2
-
3
- This is a low-priority migration item — it only matters if your code grafts onto dapp-kit's cache invalidation (e.g. you fetch a related query and want it to be invalidated when dapp-kit's mutation fires).
4
-
5
- If your app doesn't share queryKey shapes with dapp-kit, skip this file. The shape changes are a nicety, not a blocker — your existing keys still work for your own queries.
6
-
7
- ## What changed
8
-
9
- v1 was ad-hoc; v2 is canonical.
10
-
11
- | Aspect | v1 | v2 |
12
- |---|---|---|
13
- | First segment | Free-form (`'xBalances'`, `'btc-balance'`, `'api'`) | Feature directory name (`'shared'`, `'bitcoin'`, `'backend'`) |
14
- | Casing | Mixed (kebab-case in places) | camelCase exclusively |
15
- | Bigint values | Inconsistent | Always `.toString()` before going into a key |
16
- | Default `mutationKey` | Many hooks had none | Every hook has a default; consumer can override |
17
-
18
- ## Why align?
19
-
20
- Your custom queries can be invalidated by dapp-kit's mutations if they share the prefix:
21
-
22
- ```ts
23
- // @ai-snippets-skip — illustrative; `queryFn` is shown as `...` placeholder
24
- // Your custom query
25
- const { data: customAnalytics } = useQuery({
26
- queryKey: ['shared', 'xBalances', xChainId, address, 'with-analytics'],
27
- queryFn: ...,
28
- });
29
-
30
- // Dapp-kit's `useSwap` invalidates `['shared', 'xBalances', srcChainKey]`,
31
- // which is a PREFIX of your key — your query gets invalidated automatically.
32
- ```
33
-
34
- If your key starts with something else (e.g. `['my-app', 'xBalances', ...]`), dapp-kit's invalidation won't touch it — you'd need to wire your own invalidation in `mutationOptions.onSuccess`.
35
-
36
- ## Migration patterns
37
-
38
- ### Sweep your custom queryKeys
39
-
40
- If your app has custom queries that overlap with dapp-kit's domains, rename them to match v2 conventions:
41
-
42
- <!-- ai-keys-allow — v1 keys shown for migration context; the `-` lines are v1 shapes, not real v2 source keys -->
43
-
44
- ```diff
45
- const { data } = useQuery({
46
- - queryKey: ['xBalances', address, ...],
47
- + queryKey: ['shared', 'xBalances', xChainId, [token], address],
48
- queryFn: ...,
49
- });
50
-
51
- const { data } = useQuery({
52
- - queryKey: ['btc-balance', address],
53
- + queryKey: ['bitcoin', 'balance', address],
54
- queryFn: ...,
55
- });
56
- <!-- ai-keys-allow -->
57
-
58
- const { data } = useQuery({
59
- - queryKey: ['api', 'mm', userAddress],
60
- + queryKey: ['backend', 'mm', userAddress],
61
- queryFn: ...,
62
- });
63
- ```
64
-
65
- ### If you previously overrode dapp-kit's queryKeys
66
-
67
- v1 query hooks accepted `queryKey` overrides. v2 hooks own their queryKeys — the option is gone.
68
-
69
- ```diff
70
- - const { data } = useUserReservesData({
71
- - spokeProvider,
72
- - address,
73
- - queryKey: ['my-app-mm-positions'], // v1
74
- - });
75
- + // v2 — drop the queryKey override; if you needed an alias, write your own useQuery.
76
- + const { data } = useUserReservesData({
77
- + params: { spokeChainKey, userAddress: address },
78
- + });
79
- ```
80
-
81
- ### If you had your own `mutationKey` defaults
82
-
83
- v1 mutation hooks often had no default `mutationKey` — consumers set one in `mutationOptions`. v2 hooks set a sensible default (e.g. `['swap']`, `['mm', 'supply']`) — drop redundant overrides:
84
-
85
- ```diff
86
- const { mutateAsync: swap } = useSwap({
87
- mutationOptions: {
88
- - mutationKey: ['swap'], // already the default in v2
89
- retry: 5,
90
- },
91
- });
92
- ```
93
-
94
- ## Per-feature conventions
95
-
96
- See [`../../integration/reference/querykey-conventions.md`](../../integration/reference/querykey-conventions.md) for the full per-feature key tables. Use that as the reference when aligning your own keys.
97
-
98
- ## Done criteria
99
-
100
- <!-- ai-keys-allow — the bare xBalances key below is shown as a v1-style anti-example -->
101
- - [ ] No custom queryKeys overlapping with dapp-kit's domains using non-canonical first segments (e.g. `['xBalances', ...]` should become `['shared', 'xBalances', ...]`).
102
- - [ ] No `queryKey` overrides in `useFooQuery({ ..., queryKey: [...] })` patterns (the option is gone).
103
- - [ ] Optional: drop redundant default-`mutationKey` overrides in `mutationOptions`.
104
-
105
- ## Cross-references
106
-
107
- - [`../../integration/reference/querykey-conventions.md`](../../integration/reference/querykey-conventions.md) — full canonical conventions + per-feature key tables.
108
- - [`hook-signatures.md`](hook-signatures.md) — broader hook-shape changes.
@@ -1,211 +0,0 @@
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).
@@ -1,165 +0,0 @@
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.
@@ -1,89 +0,0 @@
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.
@@ -1,34 +0,0 @@
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.