@sodax/dapp-kit 1.5.6-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.
- package/README.md +300 -422
- package/ai-exported/AGENTS.md +134 -0
- package/ai-exported/integration/README.md +49 -0
- package/ai-exported/integration/ai-rules.md +79 -0
- package/ai-exported/integration/architecture.md +274 -0
- package/ai-exported/integration/features/README.md +29 -0
- package/ai-exported/integration/features/auxiliary-services.md +169 -0
- package/ai-exported/integration/features/bitcoin.md +87 -0
- package/ai-exported/integration/features/bridge.md +91 -0
- package/ai-exported/integration/features/dex.md +152 -0
- package/ai-exported/integration/features/migration.md +118 -0
- package/ai-exported/integration/features/money-market.md +116 -0
- package/ai-exported/integration/features/staking.md +123 -0
- package/ai-exported/integration/features/swap.md +101 -0
- package/ai-exported/integration/quickstart.md +187 -0
- package/ai-exported/integration/recipes/README.md +136 -0
- package/ai-exported/integration/recipes/backend-queries.md +157 -0
- package/ai-exported/integration/recipes/bitcoin.md +193 -0
- package/ai-exported/integration/recipes/bridge.md +174 -0
- package/ai-exported/integration/recipes/dex.md +204 -0
- package/ai-exported/integration/recipes/invalidations.md +115 -0
- package/ai-exported/integration/recipes/migration.md +212 -0
- package/ai-exported/integration/recipes/money-market.md +206 -0
- package/ai-exported/integration/recipes/mutation-error-handling.md +118 -0
- package/ai-exported/integration/recipes/observability.md +93 -0
- package/ai-exported/integration/recipes/setup.md +144 -0
- package/ai-exported/integration/recipes/staking.md +202 -0
- package/ai-exported/integration/recipes/swap.md +272 -0
- package/ai-exported/integration/recipes/wallet-connectivity.md +101 -0
- package/ai-exported/integration/reference/README.md +12 -0
- package/ai-exported/integration/reference/glossary.md +188 -0
- package/ai-exported/integration/reference/hooks-index.md +194 -0
- package/ai-exported/integration/reference/public-api.md +110 -0
- package/ai-exported/integration/reference/querykey-conventions.md +179 -0
- package/ai-exported/migration/README.md +60 -0
- package/ai-exported/migration/ai-rules.md +81 -0
- package/ai-exported/migration/breaking-changes/hook-signatures.md +233 -0
- package/ai-exported/migration/breaking-changes/querykey-conventions.md +108 -0
- package/ai-exported/migration/breaking-changes/result-handling.md +211 -0
- package/ai-exported/migration/breaking-changes/sdk-leakage.md +165 -0
- package/ai-exported/migration/checklist.md +89 -0
- package/ai-exported/migration/features/README.md +34 -0
- package/ai-exported/migration/features/auxiliary-services.md +114 -0
- package/ai-exported/migration/features/bitcoin.md +88 -0
- package/ai-exported/migration/features/bridge.md +123 -0
- package/ai-exported/migration/features/dex.md +101 -0
- package/ai-exported/migration/features/migration.md +120 -0
- package/ai-exported/migration/features/money-market.md +97 -0
- package/ai-exported/migration/features/staking.md +109 -0
- package/ai-exported/migration/features/swap.md +118 -0
- package/ai-exported/migration/recipes.md +188 -0
- package/ai-exported/migration/reference/README.md +15 -0
- package/ai-exported/migration/reference/deleted-hooks.md +110 -0
- package/ai-exported/migration/reference/error-shape-crosswalk.md +144 -0
- package/ai-exported/migration/reference/renamed-hooks.md +66 -0
- package/dist/index.cjs +2642 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1550 -0
- package/dist/index.d.ts +1020 -2051
- package/dist/index.mjs +1594 -1532
- package/dist/index.mjs.map +1 -1
- package/package.json +20 -10
- package/src/contexts/index.ts +0 -3
- package/src/hooks/_mutationContract.test.ts +99 -0
- package/src/hooks/backend/README.md +2 -2
- package/src/hooks/backend/index.ts +13 -13
- package/src/hooks/backend/unwrapResult.ts +1 -0
- package/src/hooks/backend/useBackendAllMoneyMarketAssets.ts +13 -45
- package/src/hooks/backend/useBackendAllMoneyMarketBorrowers.ts +29 -59
- package/src/hooks/backend/useBackendIntentByHash.ts +21 -47
- package/src/hooks/backend/useBackendIntentByTxHash.ts +23 -50
- package/src/hooks/backend/useBackendMoneyMarketAsset.ts +21 -54
- package/src/hooks/backend/useBackendMoneyMarketAssetBorrowers.ts +30 -57
- package/src/hooks/backend/useBackendMoneyMarketAssetSuppliers.ts +31 -58
- package/src/hooks/backend/useBackendMoneyMarketPosition.ts +22 -38
- package/src/hooks/backend/useBackendOrderbook.ts +27 -49
- package/src/hooks/backend/useBackendSubmitSwapTx.ts +30 -36
- package/src/hooks/backend/useBackendSubmitSwapTxStatus.ts +38 -58
- package/src/hooks/backend/useBackendUserIntents.ts +25 -63
- package/src/hooks/bitcoin/index.ts +9 -8
- package/src/hooks/bitcoin/useBitcoinBalance.ts +20 -5
- package/src/hooks/bitcoin/useExpiredUtxos.ts +26 -16
- package/src/hooks/bitcoin/useFundTradingWallet.ts +33 -30
- package/src/hooks/bitcoin/useRadfiAuth.ts +43 -40
- package/src/hooks/bitcoin/useRadfiSession.ts +53 -59
- package/src/hooks/bitcoin/useRadfiWithdraw.ts +35 -53
- package/src/hooks/bitcoin/useRenewUtxos.ts +30 -50
- package/src/hooks/bitcoin/useTradingWallet.ts +1 -1
- package/src/hooks/bitcoin/useTradingWalletBalance.ts +25 -14
- package/src/hooks/bridge/index.ts +5 -5
- package/src/hooks/bridge/useBridge.ts +29 -55
- package/src/hooks/bridge/useBridgeAllowance.ts +38 -38
- package/src/hooks/bridge/useBridgeApprove.ts +32 -57
- package/src/hooks/bridge/useGetBridgeableAmount.ts +23 -37
- package/src/hooks/bridge/useGetBridgeableTokens.ts +27 -50
- package/src/hooks/dex/index.ts +16 -16
- package/src/hooks/dex/useClaimRewards.ts +35 -54
- package/src/hooks/dex/useCreateDecreaseLiquidityParams.ts +7 -20
- package/src/hooks/dex/useCreateDepositParams.ts +7 -21
- package/src/hooks/dex/useCreateSupplyLiquidityParams.ts +13 -28
- package/src/hooks/dex/useCreateWithdrawParams.ts +7 -20
- package/src/hooks/dex/useDecreaseLiquidity.ts +40 -66
- package/src/hooks/dex/useDexAllowance.ts +29 -75
- package/src/hooks/dex/useDexApprove.ts +32 -43
- package/src/hooks/dex/useDexDeposit.ts +42 -49
- package/src/hooks/dex/useDexWithdraw.ts +32 -43
- package/src/hooks/dex/useLiquidityAmounts.ts +27 -84
- package/src/hooks/dex/usePoolBalances.ts +50 -72
- package/src/hooks/dex/usePoolData.ts +17 -43
- package/src/hooks/dex/usePools.ts +11 -38
- package/src/hooks/dex/usePositionInfo.ts +27 -62
- package/src/hooks/dex/useSupplyLiquidity.ts +80 -75
- package/src/hooks/index.ts +12 -10
- package/src/hooks/migrate/index.ts +13 -4
- package/src/hooks/migrate/useMigrateBaln.ts +42 -0
- package/src/hooks/migrate/useMigrateIcxToSoda.ts +44 -0
- package/src/hooks/migrate/useMigratebnUSD.ts +47 -0
- package/src/hooks/migrate/useMigrationAllowance.ts +76 -0
- package/src/hooks/migrate/useMigrationApprove.ts +66 -0
- package/src/hooks/migrate/useRevertMigrateSodaToIcx.ts +39 -0
- package/src/hooks/mm/index.ts +14 -12
- package/src/hooks/mm/useAToken.ts +25 -41
- package/src/hooks/mm/useATokensBalances.ts +29 -60
- package/src/hooks/mm/useBorrow.ts +38 -56
- package/src/hooks/mm/useMMAllowance.ts +37 -73
- package/src/hooks/mm/useMMApprove.ts +36 -43
- package/src/hooks/mm/useRepay.ts +33 -53
- package/src/hooks/mm/useReservesData.ts +12 -38
- package/src/hooks/mm/useReservesHumanized.ts +12 -31
- package/src/hooks/mm/useReservesList.ts +11 -31
- package/src/hooks/mm/useReservesUsdFormat.ts +15 -35
- package/src/hooks/mm/useSupply.ts +45 -51
- package/src/hooks/mm/useUserFormattedSummary.ts +32 -84
- package/src/hooks/mm/useUserReservesData.ts +27 -77
- package/src/hooks/mm/useWithdraw.ts +38 -54
- package/src/hooks/partner/index.ts +6 -0
- package/src/hooks/partner/useApproveToken.ts +42 -0
- package/src/hooks/partner/useFeeClaimSwap.ts +38 -0
- package/src/hooks/partner/useFetchAssetsBalances.ts +37 -0
- package/src/hooks/partner/useGetAutoSwapPreferences.ts +37 -0
- package/src/hooks/partner/useIsTokenApproved.ts +39 -0
- package/src/hooks/partner/useSetSwapPreference.ts +50 -0
- package/src/hooks/provider/index.ts +1 -2
- package/src/hooks/provider/useHubProvider.ts +1 -1
- package/src/hooks/recovery/index.ts +2 -0
- package/src/hooks/recovery/useHubAssetBalances.ts +43 -0
- package/src/hooks/recovery/useWithdrawHubAsset.ts +48 -0
- package/src/hooks/shared/index.ts +10 -6
- package/src/hooks/shared/types.ts +77 -0
- package/src/hooks/shared/unwrapResult.ts +19 -0
- package/src/hooks/shared/useDeriveUserWalletAddress.ts +22 -40
- package/src/hooks/shared/useEstimateGas.ts +18 -15
- package/src/hooks/shared/useGetUserHubWalletAddress.ts +25 -26
- package/src/hooks/shared/useRequestTrustline.ts +28 -61
- package/src/hooks/shared/useSafeMutation.test.ts +43 -0
- package/src/hooks/shared/useSafeMutation.ts +68 -0
- package/src/hooks/shared/useSodaxContext.ts +1 -1
- package/src/hooks/shared/useStellarTrustlineCheck.ts +30 -64
- package/src/hooks/shared/useXBalances.test.ts +113 -0
- package/src/hooks/shared/useXBalances.ts +61 -0
- package/src/hooks/staking/index.ts +18 -18
- package/src/hooks/staking/useCancelUnstake.ts +30 -41
- package/src/hooks/staking/useClaim.ts +27 -36
- package/src/hooks/staking/useConvertedAssets.ts +24 -34
- package/src/hooks/staking/useInstantUnstake.ts +33 -40
- package/src/hooks/staking/useInstantUnstakeAllowance.ts +37 -45
- package/src/hooks/staking/useInstantUnstakeApprove.ts +42 -42
- package/src/hooks/staking/useInstantUnstakeRatio.ts +24 -41
- package/src/hooks/staking/useStake.ts +32 -37
- package/src/hooks/staking/useStakeAllowance.ts +30 -43
- package/src/hooks/staking/useStakeApprove.ts +40 -40
- package/src/hooks/staking/useStakeRatio.ts +24 -40
- package/src/hooks/staking/useStakingConfig.ts +14 -27
- package/src/hooks/staking/useStakingInfo.ts +30 -38
- package/src/hooks/staking/useUnstake.ts +29 -43
- package/src/hooks/staking/useUnstakeAllowance.ts +37 -44
- package/src/hooks/staking/useUnstakeApprove.ts +40 -43
- package/src/hooks/staking/useUnstakingInfo.ts +29 -41
- package/src/hooks/staking/useUnstakingInfoWithPenalty.ts +31 -47
- package/src/hooks/swap/index.ts +8 -8
- package/src/hooks/swap/useCancelLimitOrder.ts +24 -41
- package/src/hooks/swap/useCancelSwap.ts +24 -33
- package/src/hooks/swap/useCreateLimitOrder.ts +29 -62
- package/src/hooks/swap/useQuote.ts +17 -43
- package/src/hooks/swap/useStatus.ts +22 -29
- package/src/hooks/swap/useSwap.ts +31 -49
- package/src/hooks/swap/useSwapAllowance.ts +38 -35
- package/src/hooks/swap/useSwapApprove.ts +48 -57
- package/src/index.ts +5 -3
- package/src/providers/SodaxProvider.tsx +17 -11
- package/src/providers/createSodaxQueryClient.ts +96 -0
- package/src/providers/index.ts +2 -1
- package/src/utils/dex-utils.ts +27 -5
- package/src/utils/index.ts +1 -1
- package/dist/index.d.mts +0 -2581
- package/dist/index.js +0 -2562
- package/dist/index.js.map +0 -1
- package/src/hooks/migrate/types.ts +0 -15
- package/src/hooks/migrate/useMigrate.tsx +0 -110
- package/src/hooks/migrate/useMigrationAllowance.tsx +0 -79
- package/src/hooks/migrate/useMigrationApprove.tsx +0 -129
- package/src/hooks/provider/useSpokeProvider.ts +0 -172
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Swap migration — v1 → v2 (dapp-kit)
|
|
2
|
+
|
|
3
|
+
Pair: [`../../integration/features/swap.md`](../../integration/features/swap.md).
|
|
4
|
+
|
|
5
|
+
## TL;DR
|
|
6
|
+
|
|
7
|
+
> Cross-cutting conventions (drop `spokeProvider`, single-object hook init, `mutate(vars)` for domain inputs, `mutateAsyncSafe` ergonomics) — see [`../breaking-changes/hook-signatures.md`](../breaking-changes/hook-signatures.md) and [`../breaking-changes/result-handling.md`](../breaking-changes/result-handling.md). Feature-specific deltas below:
|
|
8
|
+
|
|
9
|
+
1. **Drop `spokeProvider` from `useSwap` and `useSwapApprove` hook init.** Pass `walletProvider` (from `useWalletProvider({ xChainId: chainKey })`) into `mutate(vars)`.
|
|
10
|
+
2. **`useSwapAllowance({ params: { payload, srcChainKey, walletProvider } })`** — query inputs all nest under `params` (no top-level `spokeProvider` or `walletProvider`); the SDK request goes under `params.payload`.
|
|
11
|
+
3. **Approve hook return shape changed.** `{ approve, isLoading } = useSwapApprove(...)` → `{ mutateAsync: approve, isPending } = useSwapApprove()`.
|
|
12
|
+
4. **`mutationFn` throws on SDK `!ok`.** Either wrap `mutateAsync` in `try/catch` or use `mutateAsyncSafe` for `Result<T>` branching.
|
|
13
|
+
5. **Field on `Intent` read shape kept its name.** `Intent.srcChain` / `Intent.dstChain` are still `IntentRelayChainId` (bigint) — distinct from request-side `srcChainKey` / `dstChainKey` on action params.
|
|
14
|
+
6. **`useStatus({ params: { intentTxHash } })` — single-object query shape.** v1's positional version is gone. Key was renamed `intentHash → intentTxHash`. Return is `Result<SolverIntentStatusResponse, SolverErrorResponse> | undefined` — branch on `data?.ok` before reading status fields.
|
|
15
|
+
|
|
16
|
+
## Per-method delta
|
|
17
|
+
|
|
18
|
+
### `useSwap` — execute swap
|
|
19
|
+
|
|
20
|
+
```diff
|
|
21
|
+
function SwapButton({ intentParams }: { intentParams: CreateIntentParams }) {
|
|
22
|
+
- const swap = useSwap(spokeProvider);
|
|
23
|
+
+ const walletProvider = useWalletProvider({ xChainId: ChainKeys.BSC_MAINNET });
|
|
24
|
+
+ const { mutateAsyncSafe: swap, isPending } = useSwap();
|
|
25
|
+
|
|
26
|
+
const handleSwap = async () => {
|
|
27
|
+
+ if (!walletProvider) return;
|
|
28
|
+
- const result = await swap.mutateAsync({ params: intentParams });
|
|
29
|
+
- if (result.ok) {
|
|
30
|
+
- const { intent, intentDeliveryInfo } = result.value;
|
|
31
|
+
- /* ... */
|
|
32
|
+
- } else {
|
|
33
|
+
- toast.error(result.error.message);
|
|
34
|
+
- }
|
|
35
|
+
+ const result = await swap({ params: intentParams, walletProvider });
|
|
36
|
+
+ if (!result.ok) {
|
|
37
|
+
+ toast.error(result.error instanceof Error ? result.error.message : 'Swap failed');
|
|
38
|
+
+ return;
|
|
39
|
+
+ }
|
|
40
|
+
+ const { intent, intentDeliveryInfo } = result.value;
|
|
41
|
+
+ /* ... */
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### `useSwapApprove` — return shape
|
|
47
|
+
|
|
48
|
+
```diff
|
|
49
|
+
- const { approve, isLoading, error } = useSwapApprove(spokeProvider);
|
|
50
|
+
- await approve(intentParams);
|
|
51
|
+
+ const { mutateAsync: approve, isPending, error } = useSwapApprove();
|
|
52
|
+
+ await approve({ params: intentParams, walletProvider });
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`isLoading` → `isPending` (React Query 5 convention).
|
|
56
|
+
|
|
57
|
+
### `useSwapAllowance` — payload + srcChainKey + walletProvider all under `params`
|
|
58
|
+
|
|
59
|
+
```diff
|
|
60
|
+
- const { data: allowanceResult } = useSwapAllowance({ params: intentParams, spokeProvider });
|
|
61
|
+
+ const { data: isApproved } = useSwapAllowance({
|
|
62
|
+
+ params: { payload: intentParams, srcChainKey: ChainKeys.BSC_MAINNET, walletProvider },
|
|
63
|
+
+ });
|
|
64
|
+
+ // `data` is `boolean | undefined` (already unwrapped); no `.ok` branch needed.
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### `useStatus` — single-object shape + param renamed `intentHash → intentTxHash`
|
|
68
|
+
|
|
69
|
+
```diff
|
|
70
|
+
- const { data: status } = useStatus(intentHash);
|
|
71
|
+
+ const { data: status } = useStatus({ params: { intentTxHash } });
|
|
72
|
+
+ // `data` is `Result<SolverIntentStatusResponse, SolverErrorResponse> | undefined` —
|
|
73
|
+
+ // branch on `data?.ok` before reading `data.value.<fields>`.
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### `useQuote` — single-object shape + SDK request nested under `params.payload`
|
|
77
|
+
|
|
78
|
+
```diff
|
|
79
|
+
- const { data: quote } = useQuote({
|
|
80
|
+
- token_src: SRC_TOKEN,
|
|
81
|
+
- token_dst: DST_TOKEN,
|
|
82
|
+
- token_src_blockchain_id: BSC_MAINNET_CHAIN_ID,
|
|
83
|
+
- token_dst_blockchain_id: ARBITRUM_MAINNET_CHAIN_ID,
|
|
84
|
+
- amount,
|
|
85
|
+
- quote_type: 'exact_input',
|
|
86
|
+
- });
|
|
87
|
+
+ const { data: quote } = useQuote({
|
|
88
|
+
+ params: {
|
|
89
|
+
+ payload: {
|
|
90
|
+
+ token_src: SRC_TOKEN,
|
|
91
|
+
+ token_dst: DST_TOKEN,
|
|
92
|
+
+ token_src_blockchain_id: ChainKeys.BSC_MAINNET,
|
|
93
|
+
+ token_dst_blockchain_id: ChainKeys.ARBITRUM_MAINNET,
|
|
94
|
+
+ amount,
|
|
95
|
+
+ quote_type: 'exact_input',
|
|
96
|
+
+ },
|
|
97
|
+
+ },
|
|
98
|
+
+ });
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`SolverIntentQuoteRequest` shape unchanged. Two v2 changes: SDK request is nested under `params.payload` (not directly under `params`); constants renamed (`*_MAINNET_CHAIN_ID` → `ChainKeys.X_MAINNET`).
|
|
102
|
+
|
|
103
|
+
### `useCreateLimitOrder` / `useCancelLimitOrder` / `useCancelSwap`
|
|
104
|
+
|
|
105
|
+
Same shape changes as `useSwap` — drop `spokeProvider`, move domain inputs to `mutate(vars)`.
|
|
106
|
+
|
|
107
|
+
## Pitfalls
|
|
108
|
+
|
|
109
|
+
1. **`Intent.srcChain` / `Intent.dstChain` look like they should rename.** They didn't. Those are read-shape `IntentRelayChainId` (bigint), distinct from request-side `srcChainKey` / `dstChainKey`. Don't grep-replace.
|
|
110
|
+
2. **`useStatus` polling default.** v2 polls every 3 s unconditionally once `intentTxHash` is supplied (it does not auto-stop on terminal states — your UI should disable rendering when no longer needed, or override `queryOptions.refetchInterval: false`). Port any v1 custom polling to `queryOptions.refetchInterval`.
|
|
111
|
+
3. **`useQuote` data is `Result<T>`** — branch on `data?.ok` before reading `data.value.quoted_amount`.
|
|
112
|
+
|
|
113
|
+
## Cross-references
|
|
114
|
+
|
|
115
|
+
- [`../../integration/features/swap.md`](../../integration/features/swap.md) — v2 reference.
|
|
116
|
+
- [`../../integration/recipes/swap.md`](../../integration/recipes/swap.md) — full v2 worked example.
|
|
117
|
+
- [`../breaking-changes/hook-signatures.md`](../breaking-changes/hook-signatures.md), [`../breaking-changes/result-handling.md`](../breaking-changes/result-handling.md) — cross-cutting deltas.
|
|
118
|
+
- [`../../../../sdk/ai-exported/migration/features/swap.md`](../../../../sdk/ai-exported/migration/features/swap.md) — underlying SDK swap migration.
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# Migration recipes — `@sodax/dapp-kit` v1 → v2
|
|
2
|
+
|
|
3
|
+
Codemods, adapters, and incremental migration patterns. Use these when full conversion in one pass isn't realistic or when you want to mechanize the boring parts.
|
|
4
|
+
|
|
5
|
+
## Codemod 1: chain-id constants → ChainKeys
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# From your consumer's repo root:
|
|
9
|
+
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'
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Then add `import { ChainKeys } from '@sodax/sdk'` (or `'@sodax/dapp-kit'` — both work) where needed. tsc will flag missing imports.
|
|
13
|
+
|
|
14
|
+
For more sophisticated automation across many files, use ts-morph:
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
// @ai-snippets-skip
|
|
18
|
+
// codemod-chain-ids.ts — run with `tsx codemod-chain-ids.ts`
|
|
19
|
+
import { Project, SyntaxKind } from 'ts-morph';
|
|
20
|
+
|
|
21
|
+
const project = new Project({ tsConfigFilePath: './tsconfig.json' });
|
|
22
|
+
|
|
23
|
+
for (const file of project.getSourceFiles('src/**/*.{ts,tsx}')) {
|
|
24
|
+
let needsImport = false;
|
|
25
|
+
|
|
26
|
+
file.forEachDescendant((node) => {
|
|
27
|
+
if (node.getKind() === SyntaxKind.Identifier) {
|
|
28
|
+
const text = node.getText();
|
|
29
|
+
const m = text.match(/^([A-Z_]+)_MAINNET_CHAIN_ID$/);
|
|
30
|
+
if (m) {
|
|
31
|
+
node.replaceWithText(`ChainKeys.${m[1]}_MAINNET`);
|
|
32
|
+
needsImport = true;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
if (needsImport && !file.getImportDeclaration('@sodax/sdk')?.getNamedImports().some(n => n.getName() === 'ChainKeys')) {
|
|
38
|
+
file.addImportDeclaration({ moduleSpecifier: '@sodax/sdk', namedImports: ['ChainKeys'] });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
await project.save();
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Codemod 2: useSpokeProvider deletion
|
|
46
|
+
|
|
47
|
+
`useSpokeProvider` is gone in v2. Delete the import + usage; replace with `useWalletProvider` from `@sodax/wallet-sdk-react`.
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# 1. Find all usages first.
|
|
51
|
+
grep -rE '\buseSpokeProvider\b' src/
|
|
52
|
+
|
|
53
|
+
# 2. Manual delete + rewrite each (no safe sed for this — context varies).
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Per call site, the rewrite:
|
|
57
|
+
|
|
58
|
+
```diff
|
|
59
|
+
- import { useSpokeProvider } from '@sodax/dapp-kit';
|
|
60
|
+
- const spokeProvider = useSpokeProvider({ chainId: BSC_MAINNET_CHAIN_ID });
|
|
61
|
+
+ import { useWalletProvider } from '@sodax/wallet-sdk-react';
|
|
62
|
+
+ import { ChainKeys } from '@sodax/sdk';
|
|
63
|
+
+ const walletProvider = useWalletProvider({ xChainId: ChainKeys.BSC_MAINNET });
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Then update consumers of `spokeProvider` to use `walletProvider` instead — usually inside `mutate(vars)` payloads, sometimes inside query hook params.
|
|
67
|
+
|
|
68
|
+
## Codemod 3: invalidate*Queries utilities deletion
|
|
69
|
+
|
|
70
|
+
Most v1 consumers had `lib/invalidate*Queries.ts` files. Hook-owned invalidations make these obsolete:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Find them.
|
|
74
|
+
grep -rE '(invalidateMmQueries|invalidateSwapQueries|invalidateBridgeQueries|invalidate\w+Queries)' src/
|
|
75
|
+
|
|
76
|
+
# For each call site, delete the call. The mutation hook handles invalidation.
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
If you have a custom invalidation that dapp-kit's hooks don't know about (e.g. your own analytics view), move it into `mutationOptions.onSuccess`:
|
|
80
|
+
|
|
81
|
+
```diff
|
|
82
|
+
const { mutateAsync: supply } = useSupply({
|
|
83
|
+
+ mutationOptions: {
|
|
84
|
+
+ onSuccess: async (data, vars) => {
|
|
85
|
+
+ await queryClient.invalidateQueries({ queryKey: ['my-app', 'analytics'] });
|
|
86
|
+
+ },
|
|
87
|
+
+ },
|
|
88
|
+
});
|
|
89
|
+
- await supply({ params, spokeProvider });
|
|
90
|
+
- invalidateMmQueries(queryClient, ...); // delete
|
|
91
|
+
- await queryClient.invalidateQueries({ queryKey: ['my-app', 'analytics'] }); // delete
|
|
92
|
+
+ await supply({ params, walletProvider });
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Adapter: Result<T>-shape adapter for legacy error consumers
|
|
96
|
+
|
|
97
|
+
If your consumer code has a helper that branches on a v1 error shape (e.g. `error.code` from old per-feature classes), the minimal change is to map v2 onto v1 at the boundary:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
// adapters/v1ErrorShape.ts
|
|
101
|
+
import { isSodaxError } from '@sodax/dapp-kit';
|
|
102
|
+
|
|
103
|
+
// V1 shape: { code, message, data?: { error } }
|
|
104
|
+
export function adaptToV1ErrorShape(error: unknown): { code?: string; message?: string; data?: { error?: unknown } } | null {
|
|
105
|
+
if (!error) return null;
|
|
106
|
+
if (isSodaxError(error)) {
|
|
107
|
+
return {
|
|
108
|
+
code: error.code,
|
|
109
|
+
message: error.message,
|
|
110
|
+
data: { error: error.cause },
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
if (error instanceof Error) return { code: 'UNKNOWN', message: error.message };
|
|
114
|
+
if (typeof error === 'object') return error as { code?: string; message?: string };
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Then your existing v1-shape error handlers keep working:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
// @ai-snippets-skip
|
|
123
|
+
const { mutateAsync: swap } = useSwap();
|
|
124
|
+
try {
|
|
125
|
+
await swap({ params, walletProvider });
|
|
126
|
+
} catch (e) {
|
|
127
|
+
const adapted = adaptToV1ErrorShape(e);
|
|
128
|
+
if (adapted?.code === 'INTENT_CREATION_FAILED' /* etc. */) { /* ... */ }
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Plan to delete the adapter once you've converted error-handling code site-by-site.
|
|
133
|
+
|
|
134
|
+
## Incremental migration: feature-by-feature
|
|
135
|
+
|
|
136
|
+
If the codebase is too large for a single-pass migration, you can convert one feature at a time. The pattern:
|
|
137
|
+
|
|
138
|
+
1. **Pick a low-traffic feature first** (e.g. recovery, partner). It limits blast radius if something breaks.
|
|
139
|
+
2. **Convert that feature's call sites and approve hooks**.
|
|
140
|
+
3. **Run the app, smoke-test the feature**.
|
|
141
|
+
4. **Move on to the next feature**.
|
|
142
|
+
|
|
143
|
+
The catch: SDK-level changes are global (e.g. chain-key terminology). You can't do `xChainId` on `XToken` for swap and `chainKey` for staking — both run on the same SDK. Plan to do all SDK-level migrations in one pass first (Phase 1 + 2 of [`checklist.md`](checklist.md)), then per-feature hook-call-site work in any order (Phase 3+).
|
|
144
|
+
|
|
145
|
+
## Incremental migration: keeping v1 wrappers temporarily
|
|
146
|
+
|
|
147
|
+
If you have many call sites that share a custom wrapper hook (e.g. one your codebase named `useLegacySwap` calling v1 dapp-kit underneath), you can rewrite the wrapper's body to call v2 internally while keeping the wrapper's name and surface intact. Call sites stay unchanged.
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
// Custom wrapper that your codebase already has (with a project-specific name).
|
|
151
|
+
// Rewrite its body to call v2 dapp-kit internally; preserve the surface so
|
|
152
|
+
// existing call sites don't change yet.
|
|
153
|
+
|
|
154
|
+
import { useSwap } from '@sodax/dapp-kit';
|
|
155
|
+
import { useWalletProvider } from '@sodax/wallet-sdk-react';
|
|
156
|
+
import type { CreateIntentParams } from '@sodax/sdk';
|
|
157
|
+
|
|
158
|
+
// Function name starts with `use` because it calls React hooks (`useWalletProvider`,
|
|
159
|
+
// `useSwap`). Inside a component, call it like any other hook.
|
|
160
|
+
export function useLegacySwapAdapter(spokeProvider: unknown, params: CreateIntentParams) {
|
|
161
|
+
const walletProvider = useWalletProvider(/* derive chainKey from spokeProvider */);
|
|
162
|
+
const m = useSwap();
|
|
163
|
+
return {
|
|
164
|
+
swap: async () => {
|
|
165
|
+
if (!walletProvider) throw new Error('wallet not connected');
|
|
166
|
+
// Adapt v2 throw-on-fail back to v1 success-with-Result shape:
|
|
167
|
+
try {
|
|
168
|
+
const value = await m.mutateAsync({ params, walletProvider });
|
|
169
|
+
return { ok: true, value };
|
|
170
|
+
} catch (e) {
|
|
171
|
+
return { ok: false, error: e };
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
isLoading: m.isPending,
|
|
175
|
+
error: m.error,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Then convert call sites at your own pace. Delete the wrapper once you're done.
|
|
181
|
+
|
|
182
|
+
## Cross-references
|
|
183
|
+
|
|
184
|
+
- [`README.md`](README.md) — overview + glossary.
|
|
185
|
+
- [`checklist.md`](checklist.md) — top-down migration checklist.
|
|
186
|
+
- [`ai-rules.md`](ai-rules.md) — DO / DO NOT for the agent doing the migration.
|
|
187
|
+
- [`breaking-changes/`](breaking-changes/) — cross-cutting deltas in detail.
|
|
188
|
+
- [`features/`](features/) — per-feature porting playbooks.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Migration reference — `@sodax/dapp-kit` v1 → v2
|
|
2
|
+
|
|
3
|
+
Lookup tables for the v1 → v2 delta. Skim during migration to confirm specific renames or removals.
|
|
4
|
+
|
|
5
|
+
| File | What's in it |
|
|
6
|
+
|---|---|
|
|
7
|
+
| [`deleted-hooks.md`](deleted-hooks.md) | v1 hooks that no longer exist in v2 (`useSpokeProvider`, `invalidateMmQueries`, legacy `useMigrate`-style API). |
|
|
8
|
+
| [`renamed-hooks.md`](renamed-hooks.md) | Hooks whose name or signature changed (rare — most renames are field-level). |
|
|
9
|
+
| [`error-shape-crosswalk.md`](error-shape-crosswalk.md) | v1 error class names → v2 `SodaxError<C>` mapping; how thrown errors look at the consumer level. |
|
|
10
|
+
|
|
11
|
+
For SDK-level reference (deleted exports, renames, error code crosswalk), see [`../../../../sdk/ai-exported/migration/reference/`](../../../../sdk/ai-exported/migration/reference/) — the underlying SDK has its own reference tree.
|
|
12
|
+
|
|
13
|
+
## Pair
|
|
14
|
+
|
|
15
|
+
This `migration/reference/` tree mirrors [`../../integration/reference/`](../../integration/reference/) (which documents v2 directly). When you need both "what does v2 do" and "what changed from v1" — open both.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Deleted hooks — v1 → v2
|
|
2
|
+
|
|
3
|
+
Hooks that existed in v1 dapp-kit (or v1-style consumer-side utilities) and have no v2 equivalent.
|
|
4
|
+
|
|
5
|
+
## `useSpokeProvider`
|
|
6
|
+
|
|
7
|
+
| | |
|
|
8
|
+
|---|---|
|
|
9
|
+
| v1 path | `import { useSpokeProvider } from '@sodax/dapp-kit'` |
|
|
10
|
+
| v2 status | **DELETED** |
|
|
11
|
+
| v2 alternative | Use `useWalletProvider({ xChainId: chainKey })` from `@sodax/wallet-sdk-react`, then pass `walletProvider` directly into `mutate(vars)` for mutations or as a query-hook param. |
|
|
12
|
+
|
|
13
|
+
```diff
|
|
14
|
+
- import { useSpokeProvider } from '@sodax/dapp-kit';
|
|
15
|
+
- const spokeProvider = useSpokeProvider({ chainId: BSC_MAINNET_CHAIN_ID });
|
|
16
|
+
+ import { useWalletProvider } from '@sodax/wallet-sdk-react';
|
|
17
|
+
+ import { ChainKeys } from '@sodax/sdk';
|
|
18
|
+
+ const walletProvider = useWalletProvider({ xChainId: ChainKeys.BSC_MAINNET });
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The chain key on the action params is what routes to the right per-chain spoke service inside the SDK; there's no "spoke provider" object for consumers to construct or hold.
|
|
22
|
+
|
|
23
|
+
## `useMigrate(spokeProvider)` (and any v1 single-migration-hook variant)
|
|
24
|
+
|
|
25
|
+
| | |
|
|
26
|
+
|---|---|
|
|
27
|
+
| v1 path | A single `useMigrate(spokeProvider)` hook (often commented out by the time consumers tried to use it) |
|
|
28
|
+
| v2 status | **DELETED** |
|
|
29
|
+
| v2 alternative | Six per-action hooks: `useMigrateIcxToSoda`, `useRevertMigrateSodaToIcx`, `useMigratebnUSD`, `useMigrateBaln`, `useMigrationApprove`, `useMigrationAllowance`. |
|
|
30
|
+
|
|
31
|
+
See [`../features/migration.md`](../features/migration.md) for the full split.
|
|
32
|
+
|
|
33
|
+
## Consumer-side `invalidate*Queries` utilities
|
|
34
|
+
|
|
35
|
+
| | |
|
|
36
|
+
|---|---|
|
|
37
|
+
| v1 path | Often a `lib/invalidateMmQueries.ts` (or similar per-feature) file in the consumer codebase |
|
|
38
|
+
| v2 status | **No longer needed — DELETE** |
|
|
39
|
+
| v2 alternative | Hook-owned invalidations. Each mutation hook invalidates the relevant query keys in its own `onSuccess`. |
|
|
40
|
+
|
|
41
|
+
```diff
|
|
42
|
+
- // lib/invalidateMmQueries.ts — DELETE this file
|
|
43
|
+
- export function invalidateMmQueries(qc, srcChainKey, userAddress, token) {
|
|
44
|
+
- qc.invalidateQueries({ queryKey: ['mm', 'userReservesData', srcChainKey, userAddress] });
|
|
45
|
+
- qc.invalidateQueries({ queryKey: ['shared', 'xBalances', srcChainKey] });
|
|
46
|
+
- /* ... */
|
|
47
|
+
- }
|
|
48
|
+
|
|
49
|
+
- // call site — DROP the manual invalidation
|
|
50
|
+
- await supply({ params, spokeProvider });
|
|
51
|
+
- invalidateMmQueries(queryClient, srcChainKey, userAddress, token);
|
|
52
|
+
+ // v2 — supply hook invalidates xBalances + userReservesData itself
|
|
53
|
+
+ await supply({ params, walletProvider });
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
For cross-feature invalidations the hook can't know about (e.g. your custom analytics view), use `mutationOptions.onSuccess`:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
// @ai-snippets-skip
|
|
60
|
+
const { mutateAsync: supply } = useSupply({
|
|
61
|
+
mutationOptions: {
|
|
62
|
+
onSuccess: async (data, vars) => {
|
|
63
|
+
await queryClient.invalidateQueries({ queryKey: ['my-app', 'analytics'] });
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Approve hook return shape (`{ approve, isLoading, error }`)
|
|
70
|
+
|
|
71
|
+
| | |
|
|
72
|
+
|---|---|
|
|
73
|
+
| v1 shape | Per-feature: `useFooApprove(spokeProvider) → { approve, isLoading, error }` |
|
|
74
|
+
| v2 status | **DELETED** (return shape, not the hooks themselves) |
|
|
75
|
+
| v2 alternative | Standard `SafeUseMutationResult` — `mutateAsync` / `mutateAsyncSafe`, `isPending`, `error`. |
|
|
76
|
+
|
|
77
|
+
```diff
|
|
78
|
+
- const { approve, isLoading } = useSwapApprove(spokeProvider);
|
|
79
|
+
- await approve(params);
|
|
80
|
+
+ const { mutateAsync: approve, isPending } = useSwapApprove();
|
|
81
|
+
+ await approve({ params, walletProvider });
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
`isLoading` → `isPending` (React Query 5 convention).
|
|
85
|
+
|
|
86
|
+
## v1 individual chain-id constants (SDK-leakage)
|
|
87
|
+
|
|
88
|
+
Not strictly hooks, but they used to be importable from `@sodax/sdk` (or `@sodax/dapp-kit` re-export):
|
|
89
|
+
|
|
90
|
+
| Constant | v1 value | v2 alternative |
|
|
91
|
+
|---|---|---|
|
|
92
|
+
| `BSC_MAINNET_CHAIN_ID` | `'0x38.bsc'` | `ChainKeys.BSC_MAINNET` |
|
|
93
|
+
| `ARBITRUM_MAINNET_CHAIN_ID` | `'0xa4b1.arbitrum'` | `ChainKeys.ARBITRUM_MAINNET` |
|
|
94
|
+
| `BASE_MAINNET_CHAIN_ID` | `'0x2105.base'` | `ChainKeys.BASE_MAINNET` |
|
|
95
|
+
| `POLYGON_MAINNET_CHAIN_ID` | `'0x89.polygon'` | `ChainKeys.POLYGON_MAINNET` |
|
|
96
|
+
| `ETHEREUM_MAINNET_CHAIN_ID` | `'0x1.ethereum'` | `ChainKeys.ETHEREUM_MAINNET` |
|
|
97
|
+
| ... 11 more | ... | All under `ChainKeys.*` namespace |
|
|
98
|
+
|
|
99
|
+
Codemod with sed:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
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'
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Cross-references
|
|
106
|
+
|
|
107
|
+
- [`renamed-hooks.md`](renamed-hooks.md) — hooks whose name/signature changed (different from deletions).
|
|
108
|
+
- [`error-shape-crosswalk.md`](error-shape-crosswalk.md) — error class consolidation.
|
|
109
|
+
- [`../breaking-changes/hook-signatures.md`](../breaking-changes/hook-signatures.md) — broader hook-shape changes.
|
|
110
|
+
- [`../breaking-changes/sdk-leakage.md`](../breaking-changes/sdk-leakage.md) — SDK-level migrations leaking through.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Error shape crosswalk — v1 → v2
|
|
2
|
+
|
|
3
|
+
The shape and type of errors flowing through dapp-kit hooks changed in v2. The change is mostly SDK-level (one canonical `SodaxError<C>` replaces 7+ per-feature classes) but it surfaces in dapp-kit at the consumer level — wherever you catch or branch on errors from hooks.
|
|
4
|
+
|
|
5
|
+
## Where v2 errors appear
|
|
6
|
+
|
|
7
|
+
| Surface | v1 | v2 |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| `mutation.error` | Only on actual exceptions | Includes SDK `!ok` errors (now thrown inside `mutationFn`) |
|
|
10
|
+
| `mutation.data` | `Result<T>` (`{ ok, value, error }`) | Unwrapped success type `T`; SDK `!ok` flows to `mutation.error` |
|
|
11
|
+
| `mutateAsync` rejection | Only on exceptions | Includes SDK `!ok` rejections |
|
|
12
|
+
| `mutateAsyncSafe` `result.error` | (didn't exist) | Includes SDK `!ok` errors (re-packed from the throw) |
|
|
13
|
+
| `onError` callback | Fired only for exceptions | Fires for SDK `!ok` too |
|
|
14
|
+
|
|
15
|
+
The semantic shift is: v1 treated SDK `!ok` as "successful but with an error inside"; v2 treats it as a thrown error. See [`../breaking-changes/result-handling.md`](../breaking-changes/result-handling.md) for the full picture.
|
|
16
|
+
|
|
17
|
+
## Error class crosswalk (SDK-level — leaks through)
|
|
18
|
+
|
|
19
|
+
In v1, each SDK feature had its own error class:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
// @ai-snippets-skip — describes deleted v1 type surface, not runnable
|
|
23
|
+
// v1
|
|
24
|
+
class MoneyMarketError<C extends MoneyMarketErrorCode> extends Error { /* ... */ }
|
|
25
|
+
class IntentError<C extends IntentErrorCode> extends Error { /* ... */ }
|
|
26
|
+
class StakingError<C extends StakingErrorCode> extends Error { /* ... */ }
|
|
27
|
+
class BridgeError<C extends BridgeErrorCode> extends Error { /* ... */ }
|
|
28
|
+
class MigrationError<C extends MigrationErrorCode> extends Error { /* ... */ }
|
|
29
|
+
class AssetServiceError<C extends AssetServiceErrorCode> extends Error { /* ... */ }
|
|
30
|
+
class ConcentratedLiquidityError<C extends ConcentratedLiquidityErrorCode> extends Error { /* ... */ }
|
|
31
|
+
// ...
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
In v2, all are consolidated:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
// @ai-snippets-skip — type-shape reference; the real class is exported from @sodax/sdk
|
|
38
|
+
// v2
|
|
39
|
+
class SodaxError<C extends SodaxErrorCode = SodaxErrorCode> extends Error {
|
|
40
|
+
readonly code: C; // closed reason union (no feature prefix)
|
|
41
|
+
readonly feature: SodaxFeature; // 'swap' | 'moneyMarket' | 'bridge' | …
|
|
42
|
+
readonly cause?: unknown;
|
|
43
|
+
readonly context?: SodaxErrorContext;
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Discriminate via `(error.feature, error.code)` instead of class name.
|
|
48
|
+
|
|
49
|
+
## Error code crosswalk (key examples)
|
|
50
|
+
|
|
51
|
+
The SDK reduced the per-feature code unions to a unified 13-code reason vocabulary, with feature-specific context on `error.context.action` / `error.context.method`. Examples:
|
|
52
|
+
|
|
53
|
+
| v1 (per-feature) | v2 |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `MoneyMarketError<'CREATE_SUPPLY_INTENT_FAILED'>` | `SodaxError<'INTENT_CREATION_FAILED'>` with `feature: 'moneyMarket'`, `context.action: 'supply'` |
|
|
56
|
+
| `MoneyMarketError<'SUPPLY_FAILED'>` | `SodaxError<'EXECUTION_FAILED'>` with `feature: 'moneyMarket'`, `context.action: 'supply'` |
|
|
57
|
+
| `IntentError<'CREATE_INTENT_FAILED'>` | `SodaxError<'INTENT_CREATION_FAILED'>` with `feature: 'swap'`, `context.action: 'createIntent'` |
|
|
58
|
+
| `IntentError<'POST_EXECUTION_FAILED'>` | `SodaxError<'EXECUTION_FAILED'>` with `feature: 'swap'`, `context.phase: 'postExecution'` |
|
|
59
|
+
| `StakingError<'STAKE_FAILED'>` | `SodaxError<'EXECUTION_FAILED'>` with `feature: 'staking'`, `context.action: 'stake'` |
|
|
60
|
+
| `BridgeError<'BRIDGE_FAILED'>` | `SodaxError<'EXECUTION_FAILED'>` with `feature: 'bridge'`, `context.action: 'bridge'` |
|
|
61
|
+
| `MigrationError<'MIGRATE_BNUSD_FORWARD_FAILED'>` | `SodaxError<'EXECUTION_FAILED'>` with `feature: 'migration'`, `context.action: 'migratebnUSD'`, `context.direction: 'forward'` |
|
|
62
|
+
| `*Error<'ALLOWANCE_CHECK_FAILED'>` | `SodaxError<'ALLOWANCE_CHECK_FAILED'>` (unchanged code; new feature/context fields) |
|
|
63
|
+
| `*Error<'APPROVE_FAILED'>` | Same |
|
|
64
|
+
| `*Error<'GAS_ESTIMATION_FAILED'>` | Same |
|
|
65
|
+
| `*Error<'RELAY_TIMEOUT'>` | `SodaxError<'RELAY_TIMEOUT'>` with `relayCode: 'RELAY_TIMEOUT'` on context |
|
|
66
|
+
|
|
67
|
+
Full crosswalk (per feature): [`../../../../sdk/ai-exported/migration/reference/error-code-crosswalk.md`](../../../../sdk/ai-exported/migration/reference/error-code-crosswalk.md).
|
|
68
|
+
|
|
69
|
+
## How to migrate error-handling code
|
|
70
|
+
|
|
71
|
+
### Pattern 1: `instanceof` checks → `isSodaxError`
|
|
72
|
+
|
|
73
|
+
```diff
|
|
74
|
+
- catch (e) {
|
|
75
|
+
- if (e instanceof MoneyMarketError) {
|
|
76
|
+
- handleMmError(e.code);
|
|
77
|
+
- }
|
|
78
|
+
- }
|
|
79
|
+
+ catch (e) {
|
|
80
|
+
+ if (isSodaxError(e) && e.feature === 'moneyMarket') {
|
|
81
|
+
+ handleMmError(e.code);
|
|
82
|
+
+ }
|
|
83
|
+
+ }
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`isSodaxError` is exported from `@sodax/dapp-kit` (re-exported from `@sodax/sdk`).
|
|
87
|
+
|
|
88
|
+
### Pattern 2: switch on code
|
|
89
|
+
|
|
90
|
+
```diff
|
|
91
|
+
catch (e) {
|
|
92
|
+
- if (e instanceof IntentError) {
|
|
93
|
+
- switch (e.code) {
|
|
94
|
+
- case 'CREATE_INTENT_FAILED': /* ... */ break;
|
|
95
|
+
- case 'POST_EXECUTION_FAILED': /* ... */ break;
|
|
96
|
+
- case 'RELAY_TIMEOUT': /* ... */ break;
|
|
97
|
+
- }
|
|
98
|
+
- }
|
|
99
|
+
+ if (isSodaxError(e) && e.feature === 'swap') {
|
|
100
|
+
+ switch (e.code) {
|
|
101
|
+
+ case 'INTENT_CREATION_FAILED': /* was CREATE_INTENT_FAILED */ break;
|
|
102
|
+
+ case 'EXECUTION_FAILED': /* was POST_EXECUTION_FAILED — check e.context.phase */ break;
|
|
103
|
+
+ case 'RELAY_TIMEOUT': /* unchanged code */ break;
|
|
104
|
+
+ }
|
|
105
|
+
+ }
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Pattern 3: error-text helper
|
|
110
|
+
|
|
111
|
+
If your v1 code has a helper that maps `error.code` to a UI message, write a small adapter:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
// adapters/v1ErrorShape.ts
|
|
115
|
+
import { isSodaxError } from '@sodax/dapp-kit';
|
|
116
|
+
|
|
117
|
+
const V1_CODE_MAP: Record<string, string> = {
|
|
118
|
+
'INTENT_CREATION_FAILED': 'CREATE_INTENT_FAILED',
|
|
119
|
+
'EXECUTION_FAILED': 'POST_EXECUTION_FAILED',
|
|
120
|
+
// ... etc.
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export function adaptToV1Code(error: unknown): string | undefined {
|
|
124
|
+
if (!isSodaxError(error)) return undefined;
|
|
125
|
+
return V1_CODE_MAP[error.code] ?? error.code;
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Plan to delete the adapter once you've ported all error UI.
|
|
130
|
+
|
|
131
|
+
## Pitfalls
|
|
132
|
+
|
|
133
|
+
1. **`onError` callbacks fire MORE in v2.** They previously didn't fire for SDK `!ok` (success-path-with-error pattern). Now they do. Audit toasts / logs to make sure they're appropriate.
|
|
134
|
+
2. **`mutation.error` reads MORE in v2.** Same reason — SDK errors flow through it now.
|
|
135
|
+
3. **`isSodaxError(e)` is the cross-bundle-safe check.** Bare `instanceof SodaxError` may break in monorepos with multiple package copies (mixed ESM/CJS, etc.). Use the type guard.
|
|
136
|
+
4. **The `feature` field is your discriminator.** A `SodaxError` from a swap mutation has `feature: 'swap'`. A bridge mutation has `feature: 'bridge'`. The `code` is the reason; `feature` is the source.
|
|
137
|
+
|
|
138
|
+
## Cross-references
|
|
139
|
+
|
|
140
|
+
- [`../breaking-changes/result-handling.md`](../breaking-changes/result-handling.md) — semantic shift in `Result<T>` handling.
|
|
141
|
+
- [`../breaking-changes/sdk-leakage.md`](../breaking-changes/sdk-leakage.md) — broader SDK-side migrations.
|
|
142
|
+
- [`../../../../sdk/ai-exported/migration/breaking-changes/result-and-errors.md`](../../../../sdk/ai-exported/migration/breaking-changes/result-and-errors.md) — full SDK error-class consolidation.
|
|
143
|
+
- [`../../../../sdk/ai-exported/migration/reference/error-code-crosswalk.md`](../../../../sdk/ai-exported/migration/reference/error-code-crosswalk.md) — per-feature error code crosswalks.
|
|
144
|
+
- [`../../integration/architecture.md`](../../integration/architecture.md) § "SDK Result handling" — design rationale.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Renamed hooks — v1 → v2
|
|
2
|
+
|
|
3
|
+
Hooks whose **name** changed between versions. Most v1 → v2 changes were signature-level (single-object params, `mutateAsyncSafe`, etc.) — actual hook renames are rare. The list below is the small set.
|
|
4
|
+
|
|
5
|
+
## Hooks renamed
|
|
6
|
+
|
|
7
|
+
| v1 | v2 | Notes |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| (none significant) | | Most hook names are stable across v1 → v2 |
|
|
10
|
+
|
|
11
|
+
### Why this list is short
|
|
12
|
+
|
|
13
|
+
The v2 canonicalization pass focused on hook **shapes** (single-object params, return-shape consolidation, mutateAsyncSafe), not naming. For most consumer code, the hook name you `import { ... }`'d in v1 is still the right hook in v2 — the breaking change is in the call shape, not the import.
|
|
14
|
+
|
|
15
|
+
## Hooks whose generic / type shape changed
|
|
16
|
+
|
|
17
|
+
These keep their name but their TypeScript signature is different. Usually requires per-call-site fixes.
|
|
18
|
+
|
|
19
|
+
| Hook | v1 → v2 change |
|
|
20
|
+
|---|---|
|
|
21
|
+
| `useSwap` | Hook init: `(spokeProvider) → ({ mutationOptions })`. Vars: `{ params } → { params, walletProvider }`. |
|
|
22
|
+
| `useSwapAllowance` | Query params: `(params, spokeProvider) → { params: { payload, srcChainKey, walletProvider } }`. SDK request nested under `params.payload`. Data unwrapped to `boolean`. |
|
|
23
|
+
| `useSwapApprove` | Return: `{ approve, isLoading } → SafeUseMutationResult` (with `mutateAsync` / `isPending`). Vars accept `CreateIntentParams \| CreateLimitOrderParams`. TData is `TxReturnType<K, false>` (chain-keyed receipt union). |
|
|
24
|
+
| `useStatus` | Now `useStatus({ params: { intentTxHash } })` — single-object shape AND key renamed from `intentHash` → `intentTxHash`. Data is `Result<SolverIntentStatusResponse, SolverErrorResponse> \| undefined` (Result-wrapped). Polls 3s. |
|
|
25
|
+
| `useQuote` | Now `useQuote({ params: { payload } })` — SDK request nested under `params.payload` (NOT directly under `params`). Data is `Result<SolverIntentQuoteResponse, SolverErrorResponse> \| undefined`. Polls 3s. |
|
|
26
|
+
| `useCancelSwap` / `useCancelLimitOrder` | TVars are FLAT (no `params` wrapper): `{ srcChainKey, intent, walletProvider }`. |
|
|
27
|
+
| `useCreateLimitOrder` | Hook init: `(spokeProvider) → ({ mutationOptions })`. Vars: `{ params, walletProvider }`. mutationKey is `['swap', 'limitOrder', 'create']`. |
|
|
28
|
+
| All MM mutations (`useSupply`/etc.) | Same as `useSwap`. Plus `srcChainKey` / `srcAddress` required in params (SDK-leakage). All four actions accept optional `dstChainKey`/`dstAddress` for cross-chain delivery (not just borrow/repay). |
|
|
29
|
+
| `useMMAllowance` | Query params: `{ params: { payload: MoneyMarketParams<K> } }`. For `'borrow'` / `'withdraw'` actions: `enabled: false` — `data` stays `undefined`. |
|
|
30
|
+
| `useUserReservesData` | Param key rename: `address → userAddress`; chain key is `spokeChainKey`. |
|
|
31
|
+
| `useUserFormattedSummary` | Same. |
|
|
32
|
+
| All staking mutations | Same as MM. Plus dedicated approve hooks per token (`useStakeApprove` ↔ `useUnstakeApprove` ↔ `useInstantUnstakeApprove`). |
|
|
33
|
+
| `useStakeRatio` | Return: `Result<bigint> → [xSodaAmount, previewDepositAmount]` (unwrapped tuple — NOT Result-wrapped in v2). |
|
|
34
|
+
| `useStakingInfo` / `useUnstakingInfo` / `useUnstakingInfoWithPenalty` / `useStakingConfig` / `useInstantUnstakeRatio` / `useConvertedAssets` | All unwrapped in v2 (hooks throw on SDK `!ok`). Branch on `isError`/`error`, not `data?.ok`. |
|
|
35
|
+
| `useUnstakingInfo` | Return shape: array → object `{ userUnstakeSodaRequests, totalUnstaking }`. `UserUnstakeInfo` items expose `id` (the requestId) and `request` (original `UnstakeSodaRequest`). |
|
|
36
|
+
| All three staking allowance hooks | Query params: `{ params: { payload: Omit<<Action>Params<K>, 'action'> } }`. Data unwrapped to `boolean`. |
|
|
37
|
+
| `useBridge` | Params: `srcChainId/dstChainId/recipient → srcChainKey/dstChainKey/recipient`. Plus field renames inside `CreateBridgeIntentParams`: `srcAsset → srcToken`, `dstAsset → dstToken`. Return: tuple → `TxHashPair` object (`{ srcChainTxHash, dstChainTxHash }`). |
|
|
38
|
+
| `useBridgeAllowance` | Query params: nested `{ params: { payload, walletProvider } }`. Data unwrapped to `boolean` (queryFn returns `false` on SDK `!ok` — does NOT throw). |
|
|
39
|
+
| `useGetBridgeableAmount` | Params: 4 fields → `{ from: XToken, to: XToken }`. Return: `bigint → BridgeLimit` object (`{ amount, decimals, type: 'DEPOSIT_LIMIT' \| 'WITHDRAWAL_LIMIT' }`). |
|
|
40
|
+
| `useGetBridgeableTokens` | Params: positional → `{ params: { from, to, token } }`. |
|
|
41
|
+
| All DEX mutations | Same as MM. `useSupplyLiquidity` now handles both mint-new and increase-existing — fan-out gated by `params.tokenId` + `params.isValidPosition`. |
|
|
42
|
+
| `useDexAllowance` | Now `{ params: { payload: CreateAssetDepositParams<K> } }`. No `walletProvider` (read-only). |
|
|
43
|
+
| `PoolKey` shape | Real fields are `currency0`, `currency1`, `fee`, `hooks?`, `poolManager`, `parameters` — NOT `poolAddress`/`token0Symbol`/etc. |
|
|
44
|
+
| `useCreate*Params` builders | All take FLAT props object — NOT `{ params }`-wrapped (`useCreateDepositParams`, `useCreateWithdrawParams`, `useCreateSupplyLiquidityParams`, `useCreateDecreaseLiquidityParams`). |
|
|
45
|
+
| `useFeeClaimSwap` (partner) | Same as MM mutation pattern. TData is `IntentAutoSwapResult` (NOT `SwapResponse`). |
|
|
46
|
+
| `useXBalances` | Params: positional → `{ params: { xService, xChainId, xTokens, address } }`. All four required. `xService` injected from `@sodax/wallet-sdk-react`. |
|
|
47
|
+
| `useEstimateGas` | Mutation; vars: `EstimateGasParams<C>` (flat, not `{ params, walletProvider }`-wrapped). |
|
|
48
|
+
| `useDeriveUserWalletAddress`, `useGetUserHubWalletAddress` | Single-object query shape. |
|
|
49
|
+
| `useStellarTrustlineCheck` | Single-object shape with `{ token, amount, chainId, walletProvider }` under `params`. |
|
|
50
|
+
| `useRequestTrustline` | Custom utility hook (NOT a canonical mutation). Takes `(token: string \| undefined)` positionally, returns `{ requestTrustline, isLoading, isRequested, error, data }`. The `requestTrustline` callback takes `{ token, amount, srcChainKey, walletProvider }`. |
|
|
51
|
+
| `useBackendOrderbook` / `useBackendAllMoneyMarketBorrowers` | Pagination MUST be nested under `params`: `{ params: { pagination: { offset, limit } } }`. |
|
|
52
|
+
| `useBackendUserIntents` | Data is `UserIntentsResponse = { items: IntentResponse[], total, offset, limit }` — NOT a bare array. Access `data?.items`. |
|
|
53
|
+
| `useBackendSubmitSwapTx` | Mutation. `apiConfig` moved from hook init to `mutate(vars)`. |
|
|
54
|
+
| All migration hooks | **NEW**: 6 per-action hooks replacing v1's single `useMigrate`. See [`deleted-hooks.md`](deleted-hooks.md). |
|
|
55
|
+
| `useMigrationAllowance` | Query params nest under `params` with inner field literally named `params` (NOT `payload`): `{ params: { params: <migration-params>, action: 'migrate' \| 'revert' } }`. |
|
|
56
|
+
| `BalnMigrateParams` (used by `useMigrateBaln`) | NEW required field `stake: boolean`. `lockupPeriod` is the `LockupPeriod` enum (5 members; values in seconds, not months). |
|
|
57
|
+
| `useTradingWalletBalance` | Return is `RadfiWalletBalance = { btcSatoshi, pendingSatoshi, externalPendingSatoshi, totalUtxos }` — NOT `{ confirmed, pending }`. |
|
|
58
|
+
| `useExpiredUtxos` | Return is `RadfiUtxo[]` (with `_id`, `txid`, `vout`, `txidVout`, `satoshi`, `amount`, `address`, `isSpent`, `status`, `source`, optional `runes`). Both this and `useTradingWalletBalance` take `{ params: { walletProvider, tradingAddress } }`. |
|
|
59
|
+
| `useRadfiAuth` | TData is `RadfiAuthResult = { accessToken, refreshToken, tradingAddress }` (3 fields — `publicKey` is persisted to localStorage but NOT returned). |
|
|
60
|
+
| All Bitcoin/Radfi mutations | Standard pattern — drop hook-init args; pass through `mutate(vars)`. |
|
|
61
|
+
|
|
62
|
+
## Cross-references
|
|
63
|
+
|
|
64
|
+
- [`deleted-hooks.md`](deleted-hooks.md) — hooks that no longer exist at all.
|
|
65
|
+
- [`../breaking-changes/hook-signatures.md`](../breaking-changes/hook-signatures.md) — shape changes in detail.
|
|
66
|
+
- [`../features/`](../features/) — per-feature porting playbooks.
|