@sodax/dapp-kit 2.0.0-rc.3 → 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 (61) hide show
  1. package/README.md +9 -63
  2. package/dist/index.mjs +0 -2
  3. package/package.json +31 -20
  4. package/ai-exported/AGENTS.md +0 -134
  5. package/ai-exported/integration/README.md +0 -49
  6. package/ai-exported/integration/ai-rules.md +0 -80
  7. package/ai-exported/integration/architecture.md +0 -276
  8. package/ai-exported/integration/features/README.md +0 -29
  9. package/ai-exported/integration/features/auxiliary-services.md +0 -169
  10. package/ai-exported/integration/features/bitcoin.md +0 -87
  11. package/ai-exported/integration/features/bridge.md +0 -91
  12. package/ai-exported/integration/features/dex.md +0 -152
  13. package/ai-exported/integration/features/migration.md +0 -118
  14. package/ai-exported/integration/features/money-market.md +0 -144
  15. package/ai-exported/integration/features/staking.md +0 -123
  16. package/ai-exported/integration/features/swap.md +0 -101
  17. package/ai-exported/integration/quickstart.md +0 -187
  18. package/ai-exported/integration/recipes/README.md +0 -136
  19. package/ai-exported/integration/recipes/backend-queries.md +0 -157
  20. package/ai-exported/integration/recipes/bitcoin.md +0 -193
  21. package/ai-exported/integration/recipes/bridge.md +0 -174
  22. package/ai-exported/integration/recipes/dex.md +0 -204
  23. package/ai-exported/integration/recipes/invalidations.md +0 -115
  24. package/ai-exported/integration/recipes/migration.md +0 -212
  25. package/ai-exported/integration/recipes/money-market.md +0 -207
  26. package/ai-exported/integration/recipes/mutation-error-handling.md +0 -118
  27. package/ai-exported/integration/recipes/observability.md +0 -93
  28. package/ai-exported/integration/recipes/setup.md +0 -168
  29. package/ai-exported/integration/recipes/staking.md +0 -202
  30. package/ai-exported/integration/recipes/swap.md +0 -272
  31. package/ai-exported/integration/recipes/wallet-connectivity.md +0 -128
  32. package/ai-exported/integration/reference/README.md +0 -12
  33. package/ai-exported/integration/reference/glossary.md +0 -190
  34. package/ai-exported/integration/reference/hooks-index.md +0 -190
  35. package/ai-exported/integration/reference/public-api.md +0 -110
  36. package/ai-exported/integration/reference/querykey-conventions.md +0 -179
  37. package/ai-exported/migration/README.md +0 -60
  38. package/ai-exported/migration/ai-rules.md +0 -81
  39. package/ai-exported/migration/breaking-changes/hook-signatures.md +0 -233
  40. package/ai-exported/migration/breaking-changes/querykey-conventions.md +0 -108
  41. package/ai-exported/migration/breaking-changes/result-handling.md +0 -211
  42. package/ai-exported/migration/breaking-changes/sdk-leakage.md +0 -167
  43. package/ai-exported/migration/checklist.md +0 -89
  44. package/ai-exported/migration/features/README.md +0 -34
  45. package/ai-exported/migration/features/auxiliary-services.md +0 -114
  46. package/ai-exported/migration/features/bitcoin.md +0 -88
  47. package/ai-exported/migration/features/bridge.md +0 -160
  48. package/ai-exported/migration/features/dex.md +0 -101
  49. package/ai-exported/migration/features/migration.md +0 -120
  50. package/ai-exported/migration/features/money-market.md +0 -139
  51. package/ai-exported/migration/features/staking.md +0 -109
  52. package/ai-exported/migration/features/swap.md +0 -133
  53. package/ai-exported/migration/recipes.md +0 -185
  54. package/ai-exported/migration/reference/README.md +0 -15
  55. package/ai-exported/migration/reference/deleted-hooks.md +0 -110
  56. package/ai-exported/migration/reference/error-shape-crosswalk.md +0 -144
  57. package/ai-exported/migration/reference/renamed-hooks.md +0 -68
  58. package/dist/index.cjs +0 -2641
  59. package/dist/index.cjs.map +0 -1
  60. package/dist/index.d.cts +0 -1557
  61. package/dist/index.mjs.map +0 -1
@@ -1,152 +0,0 @@
1
- # DEX — `@sodax/dapp-kit`
2
-
3
- Concentrated-liquidity DEX (similar to Uniswap V3). Two-step flow: deposit assets to mint pool tokens, then supply liquidity to a position.
4
-
5
- Pair: [`../../migration/features/dex.md`](../../migration/features/dex.md).
6
-
7
- ## Hook surface
8
-
9
- ```ts
10
- // @ai-snippets-skip
11
- // Asset deposit / withdraw (spoke ↔ hub pool tokens)
12
- useDexDeposit({ mutationOptions });
13
- useDexWithdraw({ mutationOptions });
14
- useDexAllowance({ params: { payload: CreateAssetDepositParams<K> }, queryOptions });
15
- useDexApprove({ mutationOptions });
16
- usePoolBalances({ params, queryOptions });
17
-
18
- // Liquidity (pool tokens ↔ position)
19
- useSupplyLiquidity({ mutationOptions }); // Mint new or increase existing
20
- useDecreaseLiquidity({ mutationOptions });
21
- useClaimRewards({ mutationOptions });
22
-
23
- // Reads
24
- usePools({ queryOptions });
25
- usePoolData({ params, queryOptions });
26
- usePositionInfo({ params, queryOptions });
27
- useLiquidityAmounts({ params, queryOptions });
28
-
29
- // Param builders (compute derived params client-side) — these take a FLAT props object,
30
- // NOT a `{ params }` wrapper. They return memoized derived params that the consumer adds
31
- // `srcChainKey` + `srcAddress` to at the mutation call site.
32
- useCreateDepositParams({ tokenIndex, amount, poolData, poolSpokeAssets, dst? });
33
- useCreateWithdrawParams({ tokenIndex, amount, poolData, poolSpokeAssets, dst? });
34
- useCreateSupplyLiquidityParams({ poolData, poolKey, minPrice, maxPrice, liquidityToken0Amount, liquidityToken1Amount, slippageTolerance, positionId?, isValidPosition? });
35
- useCreateDecreaseLiquidityParams({ /* see source for fields */ });
36
- ```
37
-
38
- ## SDK param types (passed via `mutate({ params, walletProvider })`)
39
-
40
- Each dex mutation hook's TVars is `{ params: <SDKParamsType>, walletProvider, timeout? }`. The SDK param types below are what goes INSIDE `params` — they are not the TVars themselves.
41
-
42
- ```ts
43
- // @ai-snippets-skip
44
- // Deposit / withdraw — spoke chain assets → hub pool tokens (or vice versa)
45
- type CreateAssetDepositParams<K> = {
46
- srcChainKey: K;
47
- srcAddress: GetAddressType<K>;
48
- asset: string; // spoke-chain asset address
49
- amount: bigint;
50
- poolToken: string; // hub-side pool token (vault) address
51
- dst?: { chainKey: SpokeChainKey; address: string };
52
- };
53
-
54
- // Supply liquidity — `useSupplyLiquidity` fans out internally to mint-new vs
55
- // increase-existing based on params.tokenId + params.isValidPosition.
56
- // The TVars `params` field is `UseCreateSupplyLiquidityParamsResult & { srcChainKey, srcAddress }`
57
- // (the memoized output of `useCreateSupplyLiquidityParams` + the chain/address pair).
58
- // Underlying SDK type ClSupplyParams<K> (for mint-new) has NO tokenId field:
59
- type ClSupplyParams<K> = {
60
- srcChainKey: K;
61
- srcAddress: GetAddressType<K>;
62
- poolKey: PoolKey;
63
- tickLower: bigint;
64
- tickUpper: bigint;
65
- liquidity: bigint;
66
- amount0Max: bigint;
67
- amount1Max: bigint;
68
- sqrtPriceX96: bigint;
69
- };
70
- // And ClIncreaseLiquidityParams<K> = ClSupplyParams<K> & { tokenId: bigint }
71
- // for the increase-existing branch.
72
-
73
- // Decrease liquidity
74
- type ClDecreaseLiquidityParams<K> = {
75
- srcChainKey: K;
76
- srcAddress: GetAddressType<K>;
77
- poolKey: PoolKey;
78
- tokenId: bigint;
79
- liquidity: bigint;
80
- amount0Min: bigint;
81
- amount1Min: bigint;
82
- };
83
-
84
- // Claim rewards
85
- type ClClaimRewardsParams<K> = {
86
- srcChainKey: K;
87
- srcAddress: GetAddressType<K>;
88
- poolKey: PoolKey;
89
- tokenId: bigint;
90
- tickLower: bigint;
91
- tickUpper: bigint;
92
- };
93
- ```
94
-
95
- ## Param builders
96
-
97
- The `useCreate*Params` hooks compute the right derived params client-side (e.g. ERC-4626 share conversions for deposit, current tick range for liquidity). Spread the result into the mutation:
98
-
99
- ```ts
100
- // @ai-snippets-skip — illustrative; `useCreateSupplyLiquidityParams` takes a FLAT props
101
- // object (not `{ params }`-wrapped). The consumer adds `srcChainKey` + `srcAddress` at
102
- // the mutation call site.
103
- const supplyResult = useCreateSupplyLiquidityParams({
104
- poolData,
105
- poolKey,
106
- minPrice,
107
- maxPrice,
108
- liquidityToken0Amount,
109
- liquidityToken1Amount,
110
- slippageTolerance,
111
- positionId, // optional, for increase-existing
112
- isValidPosition, // optional, gates the increase-existing branch
113
- });
114
-
115
- const { mutateAsync: supply } = useSupplyLiquidity();
116
- if (supplyResult && walletProvider) {
117
- await supply({
118
- params: { ...supplyResult, srcChainKey, srcAddress },
119
- walletProvider,
120
- });
121
- }
122
- ```
123
-
124
- ## Return shapes
125
-
126
- | Hook | Returns |
127
- |---|---|
128
- | `useDexDeposit` / `useDexWithdraw` | `SafeUseMutationResult<TxHashPair, Error, UseDex(Deposit\|Withdraw)Vars<K>>` (TVars = `{ params, walletProvider, ...optional }`) |
129
- | `useDexApprove` | `SafeUseMutationResult<TxReturnType<K, false>, Error, UseDexApproveVars<K>>` — chain-keyed receipt union |
130
- | `useSupplyLiquidity` (mint or increase) | `SafeUseMutationResult<TxHashPair, Error, UseSupplyLiquidityVars<K>>` — single shape for both branches; fan-out happens inside the hook |
131
- | `useDecreaseLiquidity` / `useClaimRewards` | `SafeUseMutationResult<TxHashPair, Error, ...>` |
132
- | `useDexAllowance` | `UseQueryResult<boolean, Error>` (already unwrapped; throws on SDK `!ok`) |
133
- | `usePools` | `UseQueryResult<PoolKey[], Error>` — `staleTime: Infinity` (no auto-refresh; pools are static config) |
134
- | `usePoolData` | `UseQueryResult<PoolData, Error>` |
135
- | `usePositionInfo` | `UseQueryResult<{ positionInfo: ClPositionInfo, isValid: boolean }, Error>` — `tokenId` param is `string \| null` (NOT bigint) |
136
- | `usePoolBalances` | `UseQueryResult<{ token0Balance: bigint; token1Balance: bigint }, Error>` |
137
- | `useLiquidityAmounts` | Direct synchronous calculation (memoized via `useMemo`) — not a React Query hook |
138
-
139
- ## Gotchas
140
-
141
- 1. **Two-step flow: deposit, then supply.** First `useDexDeposit` brings the spoke asset to the hub as pool-token shares (ERC-4626). Then `useSupplyLiquidity` uses those shares to mint or grow a position. UI flows usually combine them.
142
- 2. **`useSupplyLiquidity` handles both mint-new and increase-existing.** If `params.tokenId` is provided AND that position is valid for the pool, it increases. Otherwise it mints a new position. Use `useCreateSupplyLiquidityParams` to handle the routing.
143
- 3. **Ticks are logarithmic.** `tickLower` / `tickUpper` are not prices — they're indices. Convert with viem's `Q96` math or the SDK's helpers.
144
- 4. **`usePools` never auto-refreshes.** Pools are static config — fetch once. Override `queryOptions.refetchInterval` only if you really know your config changed.
145
- 5. **`useDexAllowance` doesn't take `walletProvider`.** Read-only — derives the user from `srcAddress` in `params`.
146
- 6. **`useClaimRewards` operates per-position.** If you need to claim across multiple positions, call it once per `tokenId`. The hook invalidates the corresponding `usePositionInfo` after success.
147
-
148
- ## Cross-references
149
-
150
- - [`../recipes/dex.md`](../recipes/dex.md) — full worked examples.
151
- - [`../../migration/features/dex.md`](../../migration/features/dex.md) — v1 → v2 porting.
152
- - [`../../../../sdk/ai-exported/integration/features/dex.md`](../../../../sdk/ai-exported/integration/features/dex.md) — underlying SDK DEX surface.
@@ -1,118 +0,0 @@
1
- # Migration — `@sodax/dapp-kit`
2
-
3
- Token migration: ICX/wICX → SODA, BALN → SODA, legacy bnUSD ↔ new bnUSD. Six per-action hooks plus shared allowance/approve.
4
-
5
- Pair: [`../../migration/features/migration.md`](../../migration/features/migration.md).
6
-
7
- ## Hook surface
8
-
9
- ```ts
10
- // @ai-snippets-skip — hook-surface listing; `<inner>` is a type placeholder, not real code
11
- // Mutations (one per action)
12
- useMigrateIcxToSoda({ mutationOptions });
13
- useRevertMigrateSodaToIcx({ mutationOptions });
14
- useMigratebnUSD({ mutationOptions }); // Bidirectional (auto-detects direction)
15
- useMigrateBaln({ mutationOptions });
16
-
17
- // Allowance + approve (action-discriminated)
18
- useMigrationApprove({ mutationOptions });
19
- // useMigrationAllowance — params nest `{ params: <inner-migration-params>, action }` under the outer `params`
20
- useMigrationAllowance({ params: { params: <inner>, action: 'migrate' | 'revert' }, queryOptions });
21
- ```
22
-
23
- ## Mutation params
24
-
25
- ```ts
26
- // @ai-snippets-skip
27
- // useMigrateIcxToSoda — wICX (ICON) → SODA (Sonic)
28
- type IcxMigrateParams = {
29
- srcChainKey: IconChainKey; // typeof ChainKeys.ICON_MAINNET
30
- srcAddress: IconAddress; // `hx${string}` | `cx${string}`
31
- address: IcxTokenType; // narrow union: wICX address OR native-ICX address
32
- amount: bigint;
33
- dstAddress: Address; // `0x${string}` — Sonic recipient
34
- };
35
-
36
- // useRevertMigrateSodaToIcx — SODA (Sonic) → wICX (ICON)
37
- type IcxCreateRevertMigrationParams = {
38
- srcChainKey: SonicChainKey; // typeof ChainKeys.SONIC_MAINNET
39
- srcAddress: Address; // `0x${string}` — Sonic
40
- amount: bigint;
41
- dstAddress: IconEoaAddress; // `hx${string}` — ICON recipient
42
- };
43
-
44
- // useMigratebnUSD — bidirectional, swap srcbnUSD/dstbnUSD + chains for the other direction
45
- type UnifiedBnUSDMigrateParams<K extends SpokeChainKey> = {
46
- srcChainKey: K;
47
- srcAddress: string; // SDK keeps this loose (cross-chain)
48
- srcbnUSD: string; // legacy or new bnUSD
49
- dstChainKey: SpokeChainKey;
50
- dstbnUSD: string; // the other one
51
- amount: bigint;
52
- dstAddress: string;
53
- };
54
-
55
- // useMigrateBaln — BALN (ICON) → SODA with optional lock
56
- type BalnMigrateParams = {
57
- srcChainKey: IconChainKey;
58
- srcAddress: IconAddress;
59
- amount: bigint;
60
- lockupPeriod: LockupPeriod; // enum (values in SECONDS), see below
61
- dstAddress: Address;
62
- stake: boolean; // REQUIRED — auto-stake migrated SODA into xSODA vault
63
- };
64
-
65
- // `LockupPeriod` is an enum with 5 members (values are in seconds, NOT months):
66
- // NO_LOCKUP = 0 (0.5x reward multiplier)
67
- // SIX_MONTHS = 6 * 30 * 24 * 60 * 60 (0.75x)
68
- // TWELVE_MONTHS = 12 * 30 * 24 * 60 * 60 (1.0x)
69
- // EIGHTEEN_MONTHS = 18 * 30 * 24 * 60 * 60 (1.25x)
70
- // TWENTY_FOUR_MONTHS = 24 * 30 * 24 * 60 * 60 (1.5x)
71
-
72
- // All wrapped as TVars: { params: <ParamsType>, walletProvider }
73
- ```
74
-
75
- ## Allowance / approve
76
-
77
- The migration approve/allowance hooks are **action-discriminated** — same hook handles all migrations, with `action` disambiguating which token is being approved:
78
-
79
- ```ts
80
- // @ai-snippets-skip
81
- const { data: isApproved } = useMigrationAllowance({
82
- params: { params: bnUSDParams, action: 'migrate' }, // 'migrate' | 'revert'
83
- });
84
- const { mutateAsync: approve } = useMigrationApprove();
85
- await approve({ params: bnUSDParams, walletProvider, action: 'migrate' });
86
- ```
87
-
88
- ## Migration paths summary
89
-
90
- | Migration | Approval needed? | Hook |
91
- |---|---|---|
92
- | ICX/wICX (ICON) → SODA | No (ICON has no ERC-20 allowance) | `useMigrateIcxToSoda` |
93
- | SODA → wICX (revert) | Yes | `useRevertMigrateSodaToIcx` + `useMigrationApprove({ action: 'revert' })` |
94
- | Legacy bnUSD ↔ new bnUSD (EVM) | Yes | `useMigratebnUSD` + `useMigrationApprove({ action: 'migrate' })` |
95
- | Legacy bnUSD (Stellar/Sui) ↔ new bnUSD | Maybe (depends on chain) | Same as above |
96
- | BALN (ICON) → SODA | No | `useMigrateBaln` |
97
-
98
- ## Return shapes
99
-
100
- | Hook | Returns |
101
- |---|---|
102
- | `useMigrateIcxToSoda` / `useRevertMigrateSodaToIcx` / `useMigratebnUSD` / `useMigrateBaln` | `SafeUseMutationResult<TxHashPair, Error, ...>` |
103
- | `useMigrationApprove` | `SafeUseMutationResult<TxReturnType<K, false>, Error, ...>` — chain-keyed receipt union (EVM/Stellar differ) |
104
- | `useMigrationAllowance` | `UseQueryResult<boolean, Error>` (already unwrapped) |
105
-
106
- ## Gotchas
107
-
108
- 1. **`useMigratebnUSD` is bidirectional.** v2 detects direction from `(srcbnUSD, dstbnUSD)` token addresses. To go the other direction, swap the params; no separate hook.
109
- 2. **BALN `lockupPeriod` is the `LockupPeriod` enum, NOT a literal number union.** Use `LockupPeriod.NO_LOCKUP`, `LockupPeriod.SIX_MONTHS`, `LockupPeriod.TWELVE_MONTHS`, `LockupPeriod.EIGHTEEN_MONTHS`, or `LockupPeriod.TWENTY_FOUR_MONTHS`. Enum values are in **seconds** (e.g. `TWELVE_MONTHS = 12 * 30 * 24 * 60 * 60`), not months. Reward multiplier ranges 0.5x (no lockup) → 1.5x (24 months). Also note: `BalnMigrateParams` requires `stake: boolean` — set `true` to auto-stake migrated SODA into the xSODA vault.
110
- 3. **ICON-side migrations don't need approval.** ICON has no ERC-20 allowance mechanism.
111
- 4. **`useRevertMigrateSodaToIcx` requires SODA approval on Sonic.** Use `useMigrationAllowance` + `useMigrationApprove` with `action: 'revert'`.
112
- 5. **`useMigratebnUSD` errors include `direction: 'forward' | 'reverse'` on context.** When surfacing errors, distinguish forward vs reverse for clearer messaging.
113
-
114
- ## Cross-references
115
-
116
- - [`../recipes/migration.md`](../recipes/migration.md) — full worked examples.
117
- - [`../../migration/features/migration.md`](../../migration/features/migration.md) — v1 → v2 porting (the v1 dapp-kit had a single `useMigrate(spokeProvider)`-style hook; v2 split into 6).
118
- - [`../../../../sdk/ai-exported/integration/features/icx-bnusd-baln.md`](../../../../sdk/ai-exported/integration/features/icx-bnusd-baln.md) — underlying SDK migration surface.
@@ -1,144 +0,0 @@
1
- # Money Market — `@sodax/dapp-kit`
2
-
3
- Cross-chain lending and borrowing.
4
-
5
- Pair: [`../../migration/features/money-market.md`](../../migration/features/money-market.md).
6
-
7
- ## Hook surface
8
-
9
- ```ts
10
- // @ai-snippets-skip
11
- // User mutations (4 actions)
12
- useSupply({ mutationOptions });
13
- useWithdraw({ mutationOptions });
14
- useBorrow({ mutationOptions });
15
- useRepay({ mutationOptions });
16
-
17
- // Allowance + approve — useMMAllowance wraps the MM params under `params.payload`
18
- useMMAllowance({ params: { payload: MoneyMarketParams<K> }, queryOptions }); // disabled for borrow/withdraw (data is undefined)
19
- useMMApprove({ mutationOptions });
20
-
21
- // Reserves data (read-only)
22
- useReservesData({ queryOptions }); // All reserve data
23
- useReservesHumanized({ queryOptions }); // Decimal-normalized
24
- useReservesList({ queryOptions }); // List of reserve asset addresses
25
- useReservesUsdFormat({ queryOptions }); // With USD values
26
-
27
- // User position
28
- useUserFormattedSummary({ params, queryOptions }); // Health factor, collateral, debt
29
- useUserReservesData({ params, queryOptions }); // Per-reserve user position
30
-
31
- // aTokens
32
- useAToken({ params: { aToken }, queryOptions }); // aToken metadata (single)
33
- useATokensBalances({ params: { aTokens, spokeChainKey, userAddress }, queryOptions }); // aToken balances (batched multicall)
34
- ```
35
-
36
- ### Read-hook param shapes
37
-
38
- ```ts
39
- // @ai-snippets-skip
40
- // useUserFormattedSummary / useUserReservesData — user-position queries
41
- type UseUserFormattedSummaryParams = ReadHookParams<FormatUserSummaryResponse, {
42
- spokeChainKey: SpokeChainKey | undefined;
43
- userAddress: string | undefined;
44
- }>;
45
- // Same shape on useUserReservesData. The hook derives the hub wallet from (spokeChainKey, userAddress) internally.
46
-
47
- // useAToken — single aToken metadata; FLAT (no chain/user fields)
48
- type UseATokenParams = ReadHookParams<ATokenData, {
49
- aToken: Address | string | undefined;
50
- }>;
51
- // ATokenData = Erc20Token & { chainKey: ChainKey }
52
-
53
- // useATokensBalances — batched aToken balances
54
- type UseATokensBalancesParams = ReadHookParams<Map<Address, bigint>, {
55
- aTokens: readonly Address[];
56
- spokeChainKey: SpokeChainKey | undefined;
57
- userAddress: string | undefined;
58
- }>;
59
- // Returns a Map keyed by aToken address. The hook resolves the hub wallet from (spokeChainKey, userAddress).
60
- ```
61
-
62
- > **Read-side chain key is `spokeChainKey`, not `srcChainKey`.** Mutation hooks (`useSupply`/`useBorrow`/etc.) use `srcChainKey` because the request crosses chains and needs a source. Read hooks describe a user's position on a single spoke chain — the field is `spokeChainKey`. Applies to `useATokensBalances`, `useUserFormattedSummary`, and `useUserReservesData` (`useAToken` is metadata-only and takes neither). Don't grep-replace one for the other.
63
-
64
- ## Mutation params
65
-
66
- All four user mutations share the same TVars shape (only the `action` literal differs):
67
-
68
- ```ts
69
- // @ai-snippets-skip
70
- type UseSupplyVars<K extends SpokeChainKey = SpokeChainKey> = {
71
- params: MoneyMarketSupplyParams<K>;
72
- walletProvider: GetWalletProviderType<K>;
73
- };
74
-
75
- // MoneyMarketSupplyParams<K>:
76
- // {
77
- // srcChainKey: K;
78
- // srcAddress: GetAddressType<K>;
79
- // token: string;
80
- // amount: bigint;
81
- // action: 'supply';
82
- // dstChainKey?: SpokeChainKey; // optional cross-chain delivery
83
- // dstAddress?: string;
84
- // }
85
- ```
86
-
87
- `borrow`, `withdraw`, `repay` follow the same shape with their respective `action` literals (`'borrow'` / `'withdraw'` / `'repay'`). **All four actions** accept optional `dstChainKey`/`dstAddress` for cross-chain delivery — supply on chain A and credit collateral on chain B, withdraw from chain A into a wallet on chain B, etc.
88
-
89
- ```ts
90
- // @ai-snippets-skip
91
- const { mutateAsyncSafe: supply } = useSupply();
92
- const result = await supply({
93
- params: { srcChainKey: ChainKeys.BASE_MAINNET, srcAddress: '0x...', token: '0x...', amount: 1_000_000n, action: 'supply' },
94
- walletProvider,
95
- });
96
- if (!result.ok) return;
97
- const { srcChainTxHash, dstChainTxHash } = result.value; // TxHashPair
98
- ```
99
-
100
- ## Approve / allowance
101
-
102
- ```ts
103
- // @ai-snippets-skip
104
- // useMMAllowance reads `params.payload` (the MM params); no walletProvider — the read calls
105
- // `isAllowanceValid` with `raw: true` internally. For borrow/withdraw, returns true automatically.
106
- const { data: isApproved } = useMMAllowance({ params: { payload: supplyParams } });
107
- const { mutateAsync: approve } = useMMApprove();
108
- if (!isApproved) await approve({ params: supplyParams, walletProvider });
109
- ```
110
-
111
- `useMMAllowance` skips the on-chain check entirely for `'borrow'` / `'withdraw'` actions — the query is `enabled: false` for those, so `data` stays `undefined`. Treat "absent allowance for borrow/withdraw" as "approval not required" at the call site (these actions never need ERC-20 approval).
112
-
113
- ## Reserves data hooks
114
-
115
- | Hook | Returns | When to use |
116
- |---|---|---|
117
- | `useReservesData` | `[ReserveData[], ...]` | Raw data for custom rendering |
118
- | `useReservesHumanized` | `ReserveDataHumanized[]` | Decimal-normalized (most common for UI) |
119
- | `useReservesList` | `Address[]` | Just the reserve addresses |
120
- | `useReservesUsdFormat` | `ReserveDataWithUsd[]` | With USD price overlays |
121
- | `useUserFormattedSummary` | `{ totalCollateralUSD, totalBorrowsUSD, healthFactor, ... }` | Dashboard-ready summary |
122
- | `useUserReservesData` | `UserReserveData[]` | Per-reserve user position |
123
-
124
- ## Return shapes
125
-
126
- | Hook | Returns |
127
- |---|---|
128
- | `useSupply` / `useBorrow` / `useWithdraw` / `useRepay` | `SafeUseMutationResult<TxHashPair, Error, ...>` (`{ srcChainTxHash, dstChainTxHash }`) |
129
- | `useMMApprove` | `SafeUseMutationResult<TxReturnType<K, false>, Error, ...>` — chain-keyed receipt union |
130
- | `useMMAllowance` | `UseQueryResult<boolean, Error>` — already unwrapped; for `borrow`/`withdraw` actions the query is `enabled: false` and `data` is `undefined` |
131
- | Reserve / position hooks | `UseQueryResult<TData, Error>` — already unwrapped; queries throw on SDK `!ok` |
132
-
133
- ## Gotchas
134
-
135
- 1. **Health factor < 1.0 is liquidation territory.** Always render a warning when `useUserFormattedSummary().healthFactor < 1.05` or whatever margin your UX uses.
136
- 2. **Cross-chain delivery via `dstChainKey`/`dstAddress`** — supported on all four actions (supply / withdraw / borrow / repay). Omit for same-chain operations; don't pass `dstChainKey === srcChainKey` (let the default kick in).
137
- 3. **`useMMAllowance` is `enabled: false` for borrow/withdraw** — `data` stays `undefined` (not `true`). Treat "no allowance result for borrow/withdraw" as "approval not required" — those actions never need ERC-20 approval.
138
- 4. **Position queries take `{ spokeChainKey, userAddress }`** (NOT `srcChainKey`/`srcAddress` — those are mutation-side names). The hub wallet derivation is automatic.
139
-
140
- ## Cross-references
141
-
142
- - [`../recipes/money-market.md`](../recipes/money-market.md) — full worked examples.
143
- - [`../../migration/features/money-market.md`](../../migration/features/money-market.md) — v1 → v2 porting.
144
- - [`../../../../sdk/ai-exported/integration/features/money-market.md`](../../../../sdk/ai-exported/integration/features/money-market.md) — underlying SDK MM surface.
@@ -1,123 +0,0 @@
1
- # Staking — `@sodax/dapp-kit`
2
-
3
- SODA → xSODA staking via ERC-4626 vault. Five user actions plus reads.
4
-
5
- Pair: [`../../migration/features/staking.md`](../../migration/features/staking.md).
6
-
7
- ## Hook surface
8
-
9
- ```ts
10
- // @ai-snippets-skip
11
- // Mutations
12
- useStake({ mutationOptions });
13
- useUnstake({ mutationOptions }); // Request unstake (waiting period)
14
- useInstantUnstake({ mutationOptions }); // Instant unstake with slippage
15
- useClaim({ mutationOptions }); // Claim SODA after waiting period
16
- useCancelUnstake({ mutationOptions }); // Cancel pending unstake
17
-
18
- // Allowance + approve (one per mutation that needs approval)
19
- useStakeApprove({ mutationOptions });
20
- useUnstakeApprove({ mutationOptions });
21
- useInstantUnstakeApprove({ mutationOptions });
22
- // Allowance hooks wrap the action params (without `action`) under params.payload.
23
- // Read-only — no walletProvider needed (the SDK call uses `raw: true`).
24
- useStakeAllowance({ params: { payload: Omit<StakeParams<K>, 'action'> }, queryOptions });
25
- useUnstakeAllowance({ params: { payload: Omit<UnstakeParams<K>, 'action'> }, queryOptions });
26
- useInstantUnstakeAllowance({ params: { payload: Omit<InstantUnstakeParams<K>, 'action'> }, queryOptions });
27
-
28
- // Reads
29
- useStakingInfo({ params, queryOptions });
30
- useUnstakingInfo({ params, queryOptions });
31
- useUnstakingInfoWithPenalty({ params, queryOptions });
32
- useStakingConfig({ queryOptions });
33
- useStakeRatio({ params, queryOptions });
34
- useInstantUnstakeRatio({ params, queryOptions });
35
- useConvertedAssets({ params, queryOptions });
36
- ```
37
-
38
- ## Mutation TVars
39
-
40
- ```ts
41
- // @ai-snippets-skip
42
- type StakeParams<K> = { srcChainKey: K; srcAddress: Address; amount: bigint; minReceive: bigint; action: 'stake' };
43
- type UnstakeParams<K> = { srcChainKey: K; srcAddress: Address; amount: bigint; action: 'unstake' };
44
- type InstantUnstakeParams<K> = { srcChainKey: K; srcAddress: Address; amount: bigint; minAmount: bigint; action: 'instantUnstake' };
45
- type ClaimParams<K> = { srcChainKey: K; srcAddress: Address; requestId: bigint; amount: bigint; action: 'claim' };
46
- type CancelUnstakeParams<K> = { srcChainKey: K; srcAddress: Address; requestId: bigint; action: 'cancelUnstake' };
47
-
48
- // All wrapped as TVars: { params: <ParamsType>, walletProvider }
49
- ```
50
-
51
- ## Read shapes (key picks)
52
-
53
- ```ts
54
- // @ai-snippets-skip
55
- // useStakingInfo — user position (data is already unwrapped from Result by the hook)
56
- useStakingInfo({ params: { srcAddress, srcChainKey } })
57
- // → UseQueryResult<StakingInfo>
58
- // StakingInfo = { totalStaked: bigint, userXSodaBalance: bigint, userXSodaValue: bigint, ... }
59
-
60
- // useUnstakingInfo — pending unstake requests
61
- useUnstakingInfo({ params: { srcAddress, srcChainKey } })
62
- // → UseQueryResult<UnstakingInfo>
63
- // UnstakingInfo = { userUnstakeSodaRequests: UserUnstakeInfo[], totalUnstaking: bigint }
64
-
65
- // useUnstakingInfoWithPenalty — same with penalty annotations
66
- useUnstakingInfoWithPenalty({ params: { srcAddress, srcChainKey } })
67
- // → UseQueryResult<UnstakingInfo & { requestsWithPenalty: UnstakeRequestWithPenalty[] }>
68
- // each request adds { penalty, penaltyPercentage, claimableAmount }
69
-
70
- // useStakingConfig — protocol params (no `params` input — only `queryOptions`)
71
- useStakingConfig()
72
- // → UseQueryResult<StakingConfig>
73
- // StakingConfig = { unstakingPeriod: bigint, minUnstakingPeriod: bigint, maxPenalty: bigint }
74
-
75
- // useStakeRatio — ratio with preview (data is a tuple, not a single bigint)
76
- useStakeRatio({ params: { amount: 1_000_000_000_000_000_000n } })
77
- // → UseQueryResult<[xSodaAmount: bigint, previewDepositAmount: bigint]>
78
- // data is the tuple directly (unwrapped) — read data?.[0] / data?.[1]
79
- ```
80
-
81
- ## Approval pattern
82
-
83
- Each of stake / unstake / instantUnstake has its OWN approve hook (different tokens):
84
-
85
- | Action | Token approved | Hook |
86
- |---|---|---|
87
- | `stake` | SODA | `useStakeApprove`, `useStakeAllowance` |
88
- | `unstake` | xSODA | `useUnstakeApprove`, `useUnstakeAllowance` |
89
- | `instantUnstake` | xSODA | `useInstantUnstakeApprove`, `useInstantUnstakeAllowance` |
90
-
91
- `claim` and `cancelUnstake` don't need approval (operating on hub-side state).
92
-
93
- ## Return shapes
94
-
95
- | Hook | Returns |
96
- |---|---|
97
- All read hooks here are **already unwrapped** — they call `unwrapResult` internally so SDK `!ok` becomes a thrown error (engages `isError` / `error` / `retry`). Read `data` directly; do NOT branch on `data.ok`.
98
-
99
- | Hook | Returns |
100
- |---|---|
101
- | `useStake` / `useUnstake` / `useInstantUnstake` / `useClaim` / `useCancelUnstake` | `SafeUseMutationResult<TxHashPair, Error, ...>` |
102
- | `useStakeApprove` etc. | `SafeUseMutationResult<TxReturnType<K, false>, Error, ...>` — chain-keyed receipt union |
103
- | `useStakingInfo` | `UseQueryResult<StakingInfo, Error>` |
104
- | `useUnstakingInfo` | `UseQueryResult<UnstakingInfo, Error>` |
105
- | `useUnstakingInfoWithPenalty` | `UseQueryResult<UnstakingInfoWithPenalty, Error>` (= `UnstakingInfo & { requestsWithPenalty: UnstakeRequestWithPenalty[] }`) |
106
- | `useStakingConfig` | `UseQueryResult<StakingConfig, Error>` |
107
- | `useStakeRatio` | `UseQueryResult<[bigint, bigint], Error>` (2-tuple: `[xSodaAmount, previewDepositAmount]`) |
108
- | `useInstantUnstakeRatio` / `useConvertedAssets` | `UseQueryResult<bigint, Error>` |
109
- | `useStakeAllowance` / `useUnstakeAllowance` / `useInstantUnstakeAllowance` | `UseQueryResult<boolean, Error>` |
110
-
111
- ## Gotchas
112
-
113
- 1. **`useStakeRatio` returns a tuple, not a bigint.** `data` is `[xSodaAmount, previewDepositAmount]` (already unwrapped) — index it: `data?.[0]` for the xSODA amount. Don't treat it as a single number.
114
- 2. **Unstake penalty is piecewise, not purely linear.** Penalty is flat `maxPenalty` during the `minUnstakingPeriod`, then decays linearly to 0 by the full `unstakingPeriod`. `useStakingConfig` returns `{ unstakingPeriod, minUnstakingPeriod, maxPenalty }`. Use `useUnstakingInfoWithPenalty` to display per-request `penaltyPercentage` and `claimableAmount`.
115
- 3. **Instant unstake bypasses the waiting period but pays slippage.** Use `useInstantUnstakeRatio` to preview the effective rate, then set `minAmount` for slippage protection.
116
- 4. **`useUnstakingInfoWithPenalty` returns an object with an embedded array.** Access `data?.requestsWithPenalty` directly (already unwrapped) — do NOT chain `.value.` first. Each request is `UserUnstakeInfo & { penalty, penaltyPercentage, claimableAmount }`; the request id lives at `req.id`, NOT `req.request.requestId`.
117
- 5. **All staking reads are unwrapped** (the hook throws on SDK `!ok`). Read `data` fields directly — no `.ok` / `.value` branching. This applies to `useStakingInfo`, `useUnstakingInfo`, `useUnstakingInfoWithPenalty`, `useStakingConfig`, `useStakeRatio`, `useInstantUnstakeRatio`, `useConvertedAssets`, and all three allowance hooks.
118
-
119
- ## Cross-references
120
-
121
- - [`../recipes/staking.md`](../recipes/staking.md) — full worked examples.
122
- - [`../../migration/features/staking.md`](../../migration/features/staking.md) — v1 → v2 porting.
123
- - [`../../../../sdk/ai-exported/integration/features/staking.md`](../../../../sdk/ai-exported/integration/features/staking.md) — underlying SDK staking surface.
@@ -1,101 +0,0 @@
1
- # Swap — `@sodax/dapp-kit`
2
-
3
- Cross-chain token swaps via the intent-based solver.
4
-
5
- Pair: [`../../migration/features/swap.md`](../../migration/features/swap.md).
6
-
7
- ## Hook surface
8
-
9
- ```ts
10
- // @ai-snippets-skip
11
- // Queries — note the nested `params.payload` shape on useQuote and useSwapAllowance.
12
- // `payload` is the SDK request value (SolverIntentQuoteRequest, CreateIntentParams, etc.).
13
- useQuote({ params: { payload }, queryOptions }); // Real-time quote (3s)
14
- useSwapAllowance({ params: { payload, srcChainKey, walletProvider }, queryOptions }); // allowance (2s)
15
- useStatus({ params: { intentTxHash }, queryOptions }); // Intent execution status (3s)
16
-
17
- // Mutations — domain inputs flow through mutate(vars), see Mutation params below
18
- useSwap({ mutationOptions });
19
- useSwapApprove({ mutationOptions });
20
- useCancelSwap({ mutationOptions }); // TVars are FLAT: { srcChainKey, intent, walletProvider }
21
- useCreateLimitOrder({ mutationOptions }); // No deadline; cancel manually
22
- useCancelLimitOrder({ mutationOptions }); // TVars are FLAT: { srcChainKey, intent, walletProvider }
23
- ```
24
-
25
- (In actual code, you import each hook directly: `import { useSwap, useSwapAllowance, ... } from '@sodax/dapp-kit'`.)
26
-
27
- ## Mutation params
28
-
29
- ```ts
30
- // @ai-snippets-skip
31
- const { mutateAsyncSafe: swap } = useSwap();
32
-
33
- // vars shape (TVars):
34
- type UseSwapVars<K extends SpokeChainKey = SpokeChainKey> = Omit<SwapActionParams<K, false>, 'raw'>;
35
- // = { params: CreateIntentParams; walletProvider: GetWalletProviderType<K> }
36
-
37
- const result = await swap({ params: intentParams, walletProvider });
38
- ```
39
-
40
- `useSwapApprove` follows the same `{ params, walletProvider }` shape via `mutate(vars)`, where `params` is `CreateIntentParams<K> | CreateLimitOrderParams<K>` (the union — limit-order params also flow through `useSwapApprove`).
41
-
42
- `useCreateLimitOrder` takes `{ params: CreateLimitOrderParams; walletProvider }` (no deadline; the order persists until cancelled).
43
-
44
- **Cancel hooks are flat** (no `params` wrapper):
45
- - `useCancelSwap` takes `{ srcChainKey, intent, walletProvider }`.
46
- - `useCancelLimitOrder` takes `{ srcChainKey, intent, walletProvider }`.
47
-
48
- ## Query params
49
-
50
- ```ts
51
- // @ai-snippets-skip
52
- // useQuote — SDK request wrapped under params.payload
53
- type UseQuoteParams = ReadHookParams<
54
- Result<SolverIntentQuoteResponse, SolverErrorResponse> | undefined,
55
- { payload: SolverIntentQuoteRequest | undefined }
56
- >;
57
-
58
- // useSwapAllowance — payload + srcChainKey + walletProvider all nested under params
59
- type UseSwapAllowanceParams<K extends SpokeChainKey> = ReadHookParams<
60
- boolean,
61
- {
62
- payload: CreateIntentParams | CreateLimitOrderParams | undefined;
63
- srcChainKey: K | undefined;
64
- walletProvider: GetWalletProviderType<K> | undefined;
65
- }
66
- >;
67
-
68
- // useStatus — flat (no payload wrapper). Key is `intentTxHash` (NOT `intentHash`).
69
- // Return is Result-wrapped, like useQuote — branch on data?.ok before reading status fields.
70
- type UseStatusParams = ReadHookParams<
71
- Result<SolverIntentStatusResponse, SolverErrorResponse> | undefined,
72
- { intentTxHash: Hex | undefined }
73
- >;
74
- ```
75
-
76
- ## Return shapes
77
-
78
- | Hook | Returns |
79
- |---|---|
80
- | `useSwap` | `SafeUseMutationResult<SwapResponse, Error, UseSwapVars>` where `SwapResponse = { intent, intentDeliveryInfo, solverExecutionResponse }` |
81
- | `useSwapApprove` | `SafeUseMutationResult<TxReturnType<K, false>, Error, UseSwapApproveVars<K>>` — chain-keyed receipt union (EVM/Stellar/Sui differ) |
82
- | `useCancelSwap` | `SafeUseMutationResult<TxHashPair, Error, { srcChainKey, intent, walletProvider }>` — note FLAT TVars |
83
- | `useCancelLimitOrder` | `SafeUseMutationResult<TxHashPair, Error, { srcChainKey, intent, walletProvider }>` — note FLAT TVars |
84
- | `useCreateLimitOrder` | `SafeUseMutationResult<{ intent, intentDeliveryInfo, ... }, Error, ...>` |
85
- | `useQuote` | `UseQueryResult<Result<SolverIntentQuoteResponse, SolverErrorResponse> \| undefined, Error>` — `data?.ok` branching required; polls 3 s |
86
- | `useSwapAllowance` | `UseQueryResult<boolean, Error>` — `data` is already-unwrapped `boolean \| undefined`; truthy when approved; polls 2 s |
87
- | `useStatus` | `UseQueryResult<Result<SolverIntentStatusResponse, SolverErrorResponse> \| undefined, Error>` — Result-wrapped like `useQuote`; `data?.ok` branching required; polls 3 s |
88
-
89
- ## Gotchas
90
-
91
- 1. **`Intent.srcChain` and `Intent.dstChain` keep their v1 names.** Even though request-side params use `srcChainKey`/`dstChainKey`, the read-side `Intent` type didn't rename. Don't blanket-replace these names.
92
- 2. **Default `mutationKey` is `['swap']`.** Use `useIsMutating({ mutationKey: ['swap'] })` to get a global "any swap in flight" state. Override via `mutationOptions.mutationKey` if you want narrower scoping per-call.
93
- 3. **Quotes auto-refresh every 3s** — pause polling by setting `queryOptions.refetchInterval: false` if the quote is in a non-visible UI.
94
- 4. **Token list has duplicate addresses across chains.** `sodax.swaps.getSupportedSwapTokens()` returns `Record<SpokeChainKey, readonly XToken[]>`. Flattening it (e.g. `Object.values(...).flat()`) yields multiple tokens that share a contract address (same token deployed on different chains). When rendering a flat token list, use a composite key like `${token.address}-${token.blockchain_id}` — not `token.address` alone.
95
-
96
- ## Cross-references
97
-
98
- - [`../recipes/swap.md`](../recipes/swap.md) — full worked example.
99
- - [`../recipes/mutation-error-handling.md`](../recipes/mutation-error-handling.md) — call-shape patterns.
100
- - [`../../migration/features/swap.md`](../../migration/features/swap.md) — v1 → v2 porting.
101
- - [`../../../../sdk/ai-exported/integration/features/swap.md`](../../../../sdk/ai-exported/integration/features/swap.md) — underlying SDK swap surface.