@sodax/dapp-kit 1.5.7-beta → 2.0.0-rc.2
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 +190 -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 +1581 -1531
- package/dist/index.mjs.map +1 -1
- package/package.json +21 -11
- 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 +13 -82
- 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 -2574
- 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,204 @@
|
|
|
1
|
+
# Recipe: DEX
|
|
2
|
+
|
|
3
|
+
Concentrated liquidity positions and asset management.
|
|
4
|
+
|
|
5
|
+
**Depends on:** [setup.md](setup.md), [wallet-connectivity.md](wallet-connectivity.md)
|
|
6
|
+
|
|
7
|
+
## Hooks
|
|
8
|
+
|
|
9
|
+
### Assets
|
|
10
|
+
|
|
11
|
+
| Hook | Type | Purpose |
|
|
12
|
+
|------|------|---------|
|
|
13
|
+
| `useDexDeposit` | Mutation | Deposit assets into pool tokens |
|
|
14
|
+
| `useDexWithdraw` | Mutation | Withdraw assets from pool tokens |
|
|
15
|
+
| `useDexAllowance` | Query | Check approval for deposit |
|
|
16
|
+
| `useDexApprove` | Mutation | Approve tokens |
|
|
17
|
+
| `usePoolBalances` | Query | User's pool token balances |
|
|
18
|
+
|
|
19
|
+
### Liquidity
|
|
20
|
+
|
|
21
|
+
| Hook | Type | Purpose |
|
|
22
|
+
|------|------|---------|
|
|
23
|
+
| `useSupplyLiquidity` | Mutation | Supply liquidity to a position |
|
|
24
|
+
| `useDecreaseLiquidity` | Mutation | Remove liquidity |
|
|
25
|
+
| `useClaimRewards` | Mutation | Claim trading fees |
|
|
26
|
+
| `usePools` | Query | List available pools |
|
|
27
|
+
| `usePoolData` | Query | Pool details (price, tick, liquidity) |
|
|
28
|
+
| `usePositionInfo` | Query | Position details |
|
|
29
|
+
| `useLiquidityAmounts` | Query | Token amounts for a tick range |
|
|
30
|
+
|
|
31
|
+
### Param Builders
|
|
32
|
+
|
|
33
|
+
| Hook | Purpose |
|
|
34
|
+
|------|---------|
|
|
35
|
+
| `useCreateDepositParams` | Build deposit params with ERC-4626 conversion |
|
|
36
|
+
| `useCreateWithdrawParams` | Build withdraw params |
|
|
37
|
+
| `useCreateSupplyLiquidityParams` | Build tick range + liquidity params |
|
|
38
|
+
| `useCreateDecreaseLiquidityParams` | Build decrease params from position state |
|
|
39
|
+
|
|
40
|
+
## List Pools
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { usePools } from '@sodax/dapp-kit';
|
|
44
|
+
|
|
45
|
+
function PoolsList() {
|
|
46
|
+
// `usePools` returns `PoolKey[]` — pool keys carry `currency0`, `currency1`, `fee`,
|
|
47
|
+
// `hooks`, `poolManager`, and `parameters`. Resolve token symbols via your own
|
|
48
|
+
// token-list lookup (e.g. config-derived).
|
|
49
|
+
const { data: pools } = usePools({});
|
|
50
|
+
return (
|
|
51
|
+
<div>
|
|
52
|
+
{pools?.map((pool, i) => (
|
|
53
|
+
<div key={`${pool.currency0}-${pool.currency1}-${pool.fee}-${i}`}>
|
|
54
|
+
<h3>{pool.currency0} / {pool.currency1}</h3>
|
|
55
|
+
<p>Fee: {pool.fee / 10000}%</p>
|
|
56
|
+
</div>
|
|
57
|
+
))}
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Deposit Assets
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
import { useDexDeposit, useDexAllowance, useDexApprove } from '@sodax/dapp-kit';
|
|
67
|
+
import { useWalletProvider } from '@sodax/wallet-sdk-react';
|
|
68
|
+
import { ChainKeys, type CreateAssetDepositParams } from '@sodax/sdk';
|
|
69
|
+
|
|
70
|
+
function DepositToPool({ srcAddress }: { srcAddress: `0x${string}` }) {
|
|
71
|
+
const walletProvider = useWalletProvider({ xChainId: ChainKeys.BASE_MAINNET });
|
|
72
|
+
const depositParams: CreateAssetDepositParams<typeof ChainKeys.BASE_MAINNET> = {
|
|
73
|
+
srcChainKey: ChainKeys.BASE_MAINNET,
|
|
74
|
+
srcAddress,
|
|
75
|
+
asset: '0x0000000000000000000000000000000000000000',
|
|
76
|
+
amount: 1_000_000_000_000_000_000n,
|
|
77
|
+
poolToken: '0x0000000000000000000000000000000000000000',
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// useDexAllowance wraps CreateAssetDepositParams under params.payload. Read-only;
|
|
81
|
+
// no walletProvider needed (the SDK call uses `raw: true`).
|
|
82
|
+
const { data: isApproved } = useDexAllowance({
|
|
83
|
+
params: { payload: depositParams },
|
|
84
|
+
});
|
|
85
|
+
const { mutateAsync: approve, isPending: isApproving } = useDexApprove();
|
|
86
|
+
const { mutateAsync: deposit, isPending: isDepositing } = useDexDeposit();
|
|
87
|
+
|
|
88
|
+
const handleDeposit = async () => {
|
|
89
|
+
if (!walletProvider) return;
|
|
90
|
+
try {
|
|
91
|
+
if (!isApproved) await approve({ params: depositParams, walletProvider });
|
|
92
|
+
const txHashPair = await deposit({ params: depositParams, walletProvider });
|
|
93
|
+
console.log('Deposited:', txHashPair);
|
|
94
|
+
} catch (e) {
|
|
95
|
+
console.error(e);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<button onClick={handleDeposit} disabled={isDepositing || isApproving || !walletProvider}>
|
|
101
|
+
{isApproving ? 'Approving...' : isDepositing ? 'Depositing...' : 'Deposit'}
|
|
102
|
+
</button>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Supply Liquidity
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
// @ai-snippets-skip — illustrative flow only; `useCreateSupplyLiquidityParams` takes
|
|
111
|
+
// a flat shape `{ poolData, poolKey, minPrice, maxPrice, liquidityToken0Amount,
|
|
112
|
+
// liquidityToken1Amount, slippageTolerance }` and the consumer must add
|
|
113
|
+
// `srcChainKey` + `srcAddress` at the mutation call site. Real consumers should
|
|
114
|
+
// reference `useCreateSupplyLiquidityParams` source for the full param set.
|
|
115
|
+
import { useSupplyLiquidity, useCreateSupplyLiquidityParams } from '@sodax/dapp-kit';
|
|
116
|
+
import { useWalletProvider } from '@sodax/wallet-sdk-react';
|
|
117
|
+
import { ChainKeys } from '@sodax/sdk';
|
|
118
|
+
|
|
119
|
+
function SupplyLiquidity() {
|
|
120
|
+
const walletProvider = useWalletProvider({ xChainId: ChainKeys.BASE_MAINNET });
|
|
121
|
+
const supplyParams = useCreateSupplyLiquidityParams({
|
|
122
|
+
params: {
|
|
123
|
+
poolKey: { /* ... */ },
|
|
124
|
+
tickLower: -60000n,
|
|
125
|
+
tickUpper: 60000n,
|
|
126
|
+
amount0: 1_000_000_000_000_000_000n,
|
|
127
|
+
amount1: 1_000_000_000_000_000_000n,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
const { mutateAsync: supplyLiquidity, isPending } = useSupplyLiquidity();
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<button
|
|
134
|
+
disabled={isPending || !supplyParams || !walletProvider}
|
|
135
|
+
onClick={async () => {
|
|
136
|
+
if (!supplyParams || !walletProvider) return;
|
|
137
|
+
try {
|
|
138
|
+
const txHashPair = await supplyLiquidity({ params: supplyParams, walletProvider });
|
|
139
|
+
console.log('Supplied:', txHashPair);
|
|
140
|
+
} catch (e) {
|
|
141
|
+
console.error(e);
|
|
142
|
+
}
|
|
143
|
+
}}
|
|
144
|
+
>
|
|
145
|
+
{isPending ? 'Supplying...' : 'Supply Liquidity'}
|
|
146
|
+
</button>
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Position + Claim Rewards
|
|
152
|
+
|
|
153
|
+
```tsx
|
|
154
|
+
// @ai-snippets-skip — illustrative flow only. Real call-shape notes:
|
|
155
|
+
// - `usePositionInfo` params.tokenId is `string | null`, not bigint
|
|
156
|
+
// - `usePositionInfo` data is `{ positionInfo: ClPositionInfo, isValid: boolean }` —
|
|
157
|
+
// access `position.positionInfo.liquidity` etc.
|
|
158
|
+
// - `useClaimRewards` params shape: `{ srcChainKey, srcAddress, poolKey, tokenId,
|
|
159
|
+
// tickLower, tickUpper }` — far richer than shown.
|
|
160
|
+
// See `features/dex.md` for the canonical param types.
|
|
161
|
+
import { usePositionInfo, useClaimRewards } from '@sodax/dapp-kit';
|
|
162
|
+
import { useWalletProvider } from '@sodax/wallet-sdk-react';
|
|
163
|
+
import { ChainKeys } from '@sodax/sdk';
|
|
164
|
+
import type { PoolKey } from '@sodax/sdk';
|
|
165
|
+
|
|
166
|
+
function Position({ positionId, poolKey }: { positionId: bigint; poolKey: PoolKey }) {
|
|
167
|
+
const walletProvider = useWalletProvider({ xChainId: ChainKeys.BASE_MAINNET });
|
|
168
|
+
const { data: position } = usePositionInfo({ params: { tokenId: positionId, poolKey } });
|
|
169
|
+
const { mutateAsync: claimRewards, isPending } = useClaimRewards();
|
|
170
|
+
|
|
171
|
+
if (!position) return null;
|
|
172
|
+
return (
|
|
173
|
+
<div>
|
|
174
|
+
<p>Liquidity: {position.liquidity.toString()}</p>
|
|
175
|
+
<p>Range: [{position.tickLower}, {position.tickUpper}]</p>
|
|
176
|
+
<button
|
|
177
|
+
onClick={() => walletProvider && claimRewards({ params: { srcChainKey: ChainKeys.BASE_MAINNET, positionId }, walletProvider })}
|
|
178
|
+
disabled={isPending || !walletProvider}
|
|
179
|
+
>
|
|
180
|
+
Claim Fees
|
|
181
|
+
</button>
|
|
182
|
+
</div>
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Remove Liquidity
|
|
188
|
+
|
|
189
|
+
```tsx
|
|
190
|
+
// @ai-snippets-skip
|
|
191
|
+
const walletProvider = useWalletProvider({ xChainId: ChainKeys.BASE_MAINNET });
|
|
192
|
+
const { mutateAsync: decreaseLiquidity } = useDecreaseLiquidity();
|
|
193
|
+
|
|
194
|
+
await decreaseLiquidity({
|
|
195
|
+
params: { srcChainKey: ChainKeys.BASE_MAINNET, positionId, liquidity: 500_000n, amount0Min: 0n, amount1Min: 0n },
|
|
196
|
+
walletProvider,
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Notes
|
|
201
|
+
|
|
202
|
+
- **Two-step flow**: deposit assets (spoke → hub pool tokens) then supply liquidity (pool tokens → position).
|
|
203
|
+
- **Ticks**: logarithmic price units (like Uniswap V3). Wider range = more trades, less capital efficiency.
|
|
204
|
+
- **ERC-4626**: pool tokens are vault shares. Use `useCreateDepositParams` to handle the conversion.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Recipe: Invalidations — hook-owned, composable
|
|
2
|
+
|
|
3
|
+
Every dapp-kit mutation hook owns its own query invalidations. After a successful mutation, the hook's `onSuccess` fires invalidation calls against the relevant query keys; **then** your consumer-provided `onSuccess` runs.
|
|
4
|
+
|
|
5
|
+
## Default — invalidations just work
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { useSwap } from '@sodax/dapp-kit';
|
|
9
|
+
import type { CreateIntentParams, IEvmWalletProvider } from '@sodax/sdk';
|
|
10
|
+
|
|
11
|
+
function SwapButton({ params, walletProvider }: { params: CreateIntentParams; walletProvider: IEvmWalletProvider }) {
|
|
12
|
+
const { mutateAsync: swap } = useSwap();
|
|
13
|
+
|
|
14
|
+
const handleClick = async () => {
|
|
15
|
+
// After this resolves successfully, dapp-kit invalidates `xBalances`
|
|
16
|
+
// for the source and destination chains automatically.
|
|
17
|
+
await swap({ params, walletProvider });
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
return <button onClick={handleClick}>Swap</button>;
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
You don't need to call `queryClient.invalidateQueries` yourself. Each mutation hook knows what queries it can invalidate (e.g. `useSwap` invalidates `xBalances` for `srcChainKey` and `dstChainKey` from the variables).
|
|
25
|
+
|
|
26
|
+
## Composing your own `onSuccess`
|
|
27
|
+
|
|
28
|
+
Pass `mutationOptions.onSuccess` to run logic AFTER dapp-kit's invalidations:
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import { useSwap } from '@sodax/dapp-kit';
|
|
32
|
+
|
|
33
|
+
const { mutateAsync: swap } = useSwap({
|
|
34
|
+
mutationOptions: {
|
|
35
|
+
onSuccess: (data, vars) => {
|
|
36
|
+
// Runs AFTER dapp-kit's xBalances invalidations.
|
|
37
|
+
// `data` is the unwrapped success value (SwapResponse).
|
|
38
|
+
trackSwap(data);
|
|
39
|
+
console.log('swap_complete', { from: vars.params.srcChainKey });
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
console.log(swap);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The order is fixed:
|
|
47
|
+
|
|
48
|
+
1. `mutationFn` resolves successfully (SDK returned `{ ok: true }`).
|
|
49
|
+
2. dapp-kit's hook-internal `onSuccess` runs the invalidations.
|
|
50
|
+
3. Your `mutationOptions.onSuccess` runs.
|
|
51
|
+
4. Per-call `mutate(vars, { onSuccess })` runs (if provided).
|
|
52
|
+
|
|
53
|
+
Failed mutations never trigger any of steps 2–4 — invalidations are correctness logic, not "always run."
|
|
54
|
+
|
|
55
|
+
## What gets invalidated, by feature
|
|
56
|
+
|
|
57
|
+
Each feature mutation hook invalidates the related read keys. Common patterns:
|
|
58
|
+
|
|
59
|
+
| Mutation | Invalidates |
|
|
60
|
+
|---|---|
|
|
61
|
+
| `useSwap` | `['shared', 'xBalances', srcChainKey]`, `['shared', 'xBalances', dstChainKey]` |
|
|
62
|
+
| `useBridge` | Same as `useSwap` (xBalances on both chains). |
|
|
63
|
+
| `useSupply`, `useWithdraw`, `useBorrow`, `useRepay` | `['mm', 'userReservesData']`, `['shared', 'xBalances', srcChainKey]`, plus reserves data on the affected token. |
|
|
64
|
+
| `useStake`, `useUnstake`, `useClaim`, `useCancelUnstake`, `useInstantUnstake` | `['staking', 'info']`, `['staking', 'unstakingInfo']`, `['shared', 'xBalances', srcChainKey]`. |
|
|
65
|
+
| `useDexDeposit`, `useDexWithdraw` | `['dex', 'poolBalances']`, `['shared', 'xBalances', srcChainKey]`. |
|
|
66
|
+
| `useSupplyLiquidity`, `useDecreaseLiquidity`, `useClaimRewards` | `['dex', 'positionInfo', tokenId]`, `['dex', 'poolBalances']`. |
|
|
67
|
+
| `useMigrateIcxToSoda`, etc. | `['shared', 'xBalances']` for source + destination chains. |
|
|
68
|
+
| Approve hooks (`useSwapApprove`, etc.) | The corresponding allowance read (`['swap', 'allowance']`, etc.). |
|
|
69
|
+
|
|
70
|
+
The exact keys are derived from `vars` at success time — so a successful supply on Base only invalidates Base-side reserves, not Arbitrum's.
|
|
71
|
+
|
|
72
|
+
## Adding cross-feature invalidations
|
|
73
|
+
|
|
74
|
+
If you operate across multiple features (e.g. you have a custom hook that does `swap → migrate`), invalidate the cross-feature keys yourself in the consumer `onSuccess`:
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
78
|
+
import { useSwap } from '@sodax/dapp-kit';
|
|
79
|
+
|
|
80
|
+
const qc = useQueryClient();
|
|
81
|
+
const { mutateAsync: swap } = useSwap({
|
|
82
|
+
mutationOptions: {
|
|
83
|
+
onSuccess: async (data, vars) => {
|
|
84
|
+
// dapp-kit invalidates xBalances. We additionally want to refresh a
|
|
85
|
+
// custom analytics view that tracks completed swap volume.
|
|
86
|
+
await qc.invalidateQueries({ queryKey: ['my-app', 'swap-volume'] });
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Per-call invalidation
|
|
93
|
+
|
|
94
|
+
For one-off invalidations (only on this specific click), pass `onSuccess` to `mutate`:
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
// @ai-snippets-skip
|
|
98
|
+
await swap.mutateAsync(
|
|
99
|
+
{ params, walletProvider },
|
|
100
|
+
{ onSuccess: () => navigate(`/swap/${data.intent.intentHash}`) }
|
|
101
|
+
);
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The order is unchanged: hook invalidations → consumer `onSuccess` → per-call `onSuccess`.
|
|
105
|
+
|
|
106
|
+
## v1 → v2
|
|
107
|
+
|
|
108
|
+
In v1 dapp-kit, consumers managed invalidations themselves — most apps had a `lib/invalidate*Queries.ts` utility that fired `queryClient.invalidateQueries(...)` after each mutation. Those utilities are no longer needed in v2; delete them.
|
|
109
|
+
|
|
110
|
+
If you're migrating v1 code, see [`../../migration/breaking-changes/hook-signatures.md`](../../migration/breaking-changes/hook-signatures.md) for the full delta.
|
|
111
|
+
|
|
112
|
+
## Cross-references
|
|
113
|
+
|
|
114
|
+
- [`mutation-error-handling.md`](mutation-error-handling.md) — picking call shapes.
|
|
115
|
+
- [`../architecture.md`](../architecture.md) — `_mutationContract.test.ts` enforces the canonical `onSuccess` composition pattern.
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# Recipe: Migration
|
|
2
|
+
|
|
3
|
+
Legacy token migration (ICX, bnUSD, BALN) from the ICON ecosystem to SODAX.
|
|
4
|
+
|
|
5
|
+
**Depends on:** [setup.md](setup.md), [wallet-connectivity.md](wallet-connectivity.md)
|
|
6
|
+
|
|
7
|
+
## Hooks
|
|
8
|
+
|
|
9
|
+
| Hook | Type | Purpose |
|
|
10
|
+
|------|------|---------|
|
|
11
|
+
| `useMigrateIcxToSoda` | Mutation | ICX/wICX (ICON) → SODA (Sonic) |
|
|
12
|
+
| `useRevertMigrateSodaToIcx` | Mutation | SODA (Sonic) → wICX (ICON) |
|
|
13
|
+
| `useMigratebnUSD` | Mutation | Legacy bnUSD ↔ new bnUSD (bidirectional, any spoke chain) |
|
|
14
|
+
| `useMigrateBaln` | Mutation | BALN (ICON) → SODA (Sonic) with optional lock period |
|
|
15
|
+
| `useMigrationApprove` | Mutation | Approve token spending before migration |
|
|
16
|
+
| `useMigrationAllowance` | Query | Check if approval is needed |
|
|
17
|
+
|
|
18
|
+
## Migration Paths
|
|
19
|
+
|
|
20
|
+
| From | To | Reversible | Approval needed |
|
|
21
|
+
|------|----|-----------|----------------|
|
|
22
|
+
| ICX/wICX (ICON) | SODA (Sonic) | Yes (use `useRevertMigrateSodaToIcx`) | No (ICON has no ERC-20 allowance) |
|
|
23
|
+
| BALN (ICON) | SODA (Sonic) | No | No |
|
|
24
|
+
| Legacy bnUSD (EVM/Stellar/ICON) | New bnUSD | Yes (same hook, swap src/dst) | Yes (EVM/Stellar sources) |
|
|
25
|
+
|
|
26
|
+
## ICX to SODA
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import { useMigrateIcxToSoda } from '@sodax/dapp-kit';
|
|
30
|
+
import { useWalletProvider } from '@sodax/wallet-sdk-react';
|
|
31
|
+
import { ChainKeys, type IconAddress } from '@sodax/sdk';
|
|
32
|
+
|
|
33
|
+
function IcxMigration({ srcAddress, dstAddress }: { srcAddress: IconAddress; dstAddress: `0x${string}` }) {
|
|
34
|
+
const walletProvider = useWalletProvider({ xChainId: ChainKeys.ICON_MAINNET });
|
|
35
|
+
const { mutateAsync: migrate, isPending } = useMigrateIcxToSoda();
|
|
36
|
+
|
|
37
|
+
const handleMigrate = async () => {
|
|
38
|
+
if (!walletProvider) return;
|
|
39
|
+
try {
|
|
40
|
+
const txHashPair = await migrate({
|
|
41
|
+
params: {
|
|
42
|
+
srcChainKey: ChainKeys.ICON_MAINNET,
|
|
43
|
+
srcAddress,
|
|
44
|
+
// `address` must be the wICX or native-ICX token address — typed as the
|
|
45
|
+
// narrow IcxTokenType union from @sodax/sdk's ICON chain config.
|
|
46
|
+
address: 'cx3975b43d260fb8ec802cef6e60c2f4d07486f11d', // wICX on ICON mainnet
|
|
47
|
+
amount: 1_000_000_000_000_000_000n,
|
|
48
|
+
dstAddress, // Sonic recipient address
|
|
49
|
+
},
|
|
50
|
+
walletProvider,
|
|
51
|
+
});
|
|
52
|
+
console.log('Migrated:', txHashPair);
|
|
53
|
+
} catch (e) {
|
|
54
|
+
console.error(e);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<button onClick={handleMigrate} disabled={isPending || !walletProvider}>
|
|
60
|
+
{isPending ? 'Migrating...' : 'Migrate ICX to SODA'}
|
|
61
|
+
</button>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Revert SODA → wICX
|
|
67
|
+
|
|
68
|
+
Requires approval — SODA is an EVM token on Sonic.
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
import { useMigrationAllowance, useMigrationApprove, useRevertMigrateSodaToIcx } from '@sodax/dapp-kit';
|
|
72
|
+
import { useWalletProvider } from '@sodax/wallet-sdk-react';
|
|
73
|
+
import { ChainKeys } from '@sodax/sdk';
|
|
74
|
+
import type { IcxCreateRevertMigrationParams } from '@sodax/sdk';
|
|
75
|
+
|
|
76
|
+
function RevertMigration({ srcAddress }: { srcAddress: `0x${string}` }) {
|
|
77
|
+
const walletProvider = useWalletProvider({ xChainId: ChainKeys.SONIC_MAINNET });
|
|
78
|
+
|
|
79
|
+
const revertParams: IcxCreateRevertMigrationParams = {
|
|
80
|
+
srcChainKey: ChainKeys.SONIC_MAINNET,
|
|
81
|
+
srcAddress,
|
|
82
|
+
amount: 1_000_000_000_000_000_000n,
|
|
83
|
+
dstAddress: 'hx...', // ICON recipient address
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const { data: isApproved } = useMigrationAllowance({
|
|
87
|
+
params: { params: revertParams, action: 'revert' },
|
|
88
|
+
});
|
|
89
|
+
const { mutateAsync: approve, isPending: isApproving } = useMigrationApprove();
|
|
90
|
+
const { mutateAsync: revert, isPending: isReverting } = useRevertMigrateSodaToIcx();
|
|
91
|
+
|
|
92
|
+
const handleRevert = async () => {
|
|
93
|
+
if (!walletProvider) return;
|
|
94
|
+
try {
|
|
95
|
+
if (!isApproved) {
|
|
96
|
+
await approve({ params: revertParams, walletProvider, action: 'revert' });
|
|
97
|
+
}
|
|
98
|
+
const txHashPair = await revert({ params: revertParams, walletProvider });
|
|
99
|
+
console.log('Reverted:', txHashPair);
|
|
100
|
+
} catch (e) {
|
|
101
|
+
console.error(e);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<button onClick={handleRevert} disabled={isReverting || isApproving || !walletProvider}>
|
|
107
|
+
{isApproving ? 'Approving...' : isReverting ? 'Reverting...' : 'Revert to wICX'}
|
|
108
|
+
</button>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## BALN to SODA (with optional lock period)
|
|
114
|
+
|
|
115
|
+
BALN migration does not require approval (ICON chain, no ERC-20 allowance). Longer lock period = higher SODA reward multiplier.
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
import { useMigrateBaln } from '@sodax/dapp-kit';
|
|
119
|
+
import { useWalletProvider } from '@sodax/wallet-sdk-react';
|
|
120
|
+
import { ChainKeys, LockupPeriod, type IconAddress } from '@sodax/sdk';
|
|
121
|
+
|
|
122
|
+
function BalnMigration({ srcAddress, dstAddress }: { srcAddress: IconAddress; dstAddress: `0x${string}` }) {
|
|
123
|
+
const walletProvider = useWalletProvider({ xChainId: ChainKeys.ICON_MAINNET });
|
|
124
|
+
const { mutateAsync: migrateBaln, isPending } = useMigrateBaln();
|
|
125
|
+
|
|
126
|
+
const handleMigrate = async () => {
|
|
127
|
+
if (!walletProvider) return;
|
|
128
|
+
try {
|
|
129
|
+
const txHashPair = await migrateBaln({
|
|
130
|
+
params: {
|
|
131
|
+
srcChainKey: ChainKeys.ICON_MAINNET,
|
|
132
|
+
srcAddress,
|
|
133
|
+
amount: 100_000_000_000_000_000_000n,
|
|
134
|
+
// LockupPeriod is an enum in seconds: NO_LOCKUP (0.5x reward),
|
|
135
|
+
// SIX_MONTHS (0.75x), TWELVE_MONTHS (1.0x), EIGHTEEN_MONTHS (1.25x),
|
|
136
|
+
// TWENTY_FOUR_MONTHS (1.5x).
|
|
137
|
+
lockupPeriod: LockupPeriod.TWELVE_MONTHS,
|
|
138
|
+
dstAddress,
|
|
139
|
+
stake: true, // Auto-stake the migrated SODA into the xSODA vault
|
|
140
|
+
},
|
|
141
|
+
walletProvider,
|
|
142
|
+
});
|
|
143
|
+
console.log('BALN migrated:', txHashPair);
|
|
144
|
+
} catch (e) {
|
|
145
|
+
console.error(e);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
return (
|
|
150
|
+
<button onClick={handleMigrate} disabled={isPending || !walletProvider}>
|
|
151
|
+
{isPending ? 'Migrating...' : 'Migrate BALN to SODA'}
|
|
152
|
+
</button>
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## bnUSD Migration (bidirectional)
|
|
158
|
+
|
|
159
|
+
Works for legacy ↔ new bnUSD across spoke chains. May require approval on EVM/Stellar sources.
|
|
160
|
+
|
|
161
|
+
```tsx
|
|
162
|
+
import { useMigratebnUSD, useMigrationAllowance, useMigrationApprove } from '@sodax/dapp-kit';
|
|
163
|
+
import { useWalletProvider } from '@sodax/wallet-sdk-react';
|
|
164
|
+
import { ChainKeys } from '@sodax/sdk';
|
|
165
|
+
import type { UnifiedBnUSDMigrateParams } from '@sodax/sdk';
|
|
166
|
+
|
|
167
|
+
function BnUSDMigration({ srcAddress }: { srcAddress: string }) {
|
|
168
|
+
const walletProvider = useWalletProvider({ xChainId: ChainKeys.BASE_MAINNET });
|
|
169
|
+
|
|
170
|
+
const bnUSDParams: UnifiedBnUSDMigrateParams<typeof ChainKeys.BASE_MAINNET> = {
|
|
171
|
+
srcChainKey: ChainKeys.BASE_MAINNET,
|
|
172
|
+
srcAddress,
|
|
173
|
+
srcbnUSD: '0x...', // legacy bnUSD address on Base
|
|
174
|
+
dstChainKey: ChainKeys.ARBITRUM_MAINNET,
|
|
175
|
+
dstbnUSD: '0x...', // new bnUSD address on Arbitrum
|
|
176
|
+
amount: 1_000_000n, // 6 decimals
|
|
177
|
+
dstAddress: srcAddress,
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const { data: isApproved } = useMigrationAllowance({
|
|
181
|
+
params: { params: bnUSDParams, action: 'migrate' },
|
|
182
|
+
});
|
|
183
|
+
const { mutateAsync: approve, isPending: isApproving } = useMigrationApprove();
|
|
184
|
+
const { mutateAsync: migratebnUSD, isPending: isMigrating } = useMigratebnUSD();
|
|
185
|
+
|
|
186
|
+
const handleMigrate = async () => {
|
|
187
|
+
if (!walletProvider) return;
|
|
188
|
+
try {
|
|
189
|
+
if (!isApproved) {
|
|
190
|
+
await approve({ params: bnUSDParams, walletProvider, action: 'migrate' });
|
|
191
|
+
}
|
|
192
|
+
const txHashPair = await migratebnUSD({ params: bnUSDParams, walletProvider });
|
|
193
|
+
console.log('bnUSD migrated:', txHashPair);
|
|
194
|
+
} catch (e) {
|
|
195
|
+
console.error(e);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
return (
|
|
200
|
+
<button onClick={handleMigrate} disabled={isMigrating || isApproving || !walletProvider}>
|
|
201
|
+
{isApproving ? 'Approving...' : isMigrating ? 'Migrating...' : 'Migrate bnUSD'}
|
|
202
|
+
</button>
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Notes
|
|
208
|
+
|
|
209
|
+
- **ICX and BALN forward migrations** don't require approval — ICON has no ERC-20 allowance mechanism.
|
|
210
|
+
- **SODA → ICX revert** and **EVM/Stellar bnUSD sources** require approval before migrating.
|
|
211
|
+
- **BALN lock periods**: `0` = 0.5x reward, `6` = 0.75x, `12` = 1.0x, `24` = 1.5x (months).
|
|
212
|
+
- `useMigratebnUSD` is bidirectional — swap `srcbnUSD`/`dstbnUSD` and `srcChainKey`/`dstChainKey` to go the other direction.
|