@sodax/skills 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 (197) hide show
  1. package/.claude-plugin/plugin.json +13 -0
  2. package/AGENTS.md +81 -0
  3. package/LICENSE +21 -0
  4. package/README.md +49 -0
  5. package/knowledge/dapp-kit/AGENTS.md +50 -0
  6. package/knowledge/dapp-kit/integration/README.md +49 -0
  7. package/knowledge/dapp-kit/integration/ai-rules.md +80 -0
  8. package/knowledge/dapp-kit/integration/architecture.md +276 -0
  9. package/knowledge/dapp-kit/integration/features/README.md +29 -0
  10. package/knowledge/dapp-kit/integration/features/auxiliary-services.md +169 -0
  11. package/knowledge/dapp-kit/integration/features/bitcoin.md +87 -0
  12. package/knowledge/dapp-kit/integration/features/bridge.md +91 -0
  13. package/knowledge/dapp-kit/integration/features/dex.md +152 -0
  14. package/knowledge/dapp-kit/integration/features/migration.md +118 -0
  15. package/knowledge/dapp-kit/integration/features/money-market.md +144 -0
  16. package/knowledge/dapp-kit/integration/features/staking.md +123 -0
  17. package/knowledge/dapp-kit/integration/features/swap.md +101 -0
  18. package/knowledge/dapp-kit/integration/quickstart.md +188 -0
  19. package/knowledge/dapp-kit/integration/recipes/README.md +136 -0
  20. package/knowledge/dapp-kit/integration/recipes/backend-queries.md +157 -0
  21. package/knowledge/dapp-kit/integration/recipes/bitcoin.md +193 -0
  22. package/knowledge/dapp-kit/integration/recipes/bridge.md +174 -0
  23. package/knowledge/dapp-kit/integration/recipes/dex.md +204 -0
  24. package/knowledge/dapp-kit/integration/recipes/invalidations.md +115 -0
  25. package/knowledge/dapp-kit/integration/recipes/migration.md +212 -0
  26. package/knowledge/dapp-kit/integration/recipes/money-market.md +207 -0
  27. package/knowledge/dapp-kit/integration/recipes/mutation-error-handling.md +118 -0
  28. package/knowledge/dapp-kit/integration/recipes/observability.md +93 -0
  29. package/knowledge/dapp-kit/integration/recipes/setup.md +168 -0
  30. package/knowledge/dapp-kit/integration/recipes/staking.md +202 -0
  31. package/knowledge/dapp-kit/integration/recipes/swap.md +272 -0
  32. package/knowledge/dapp-kit/integration/recipes/wallet-connectivity.md +128 -0
  33. package/knowledge/dapp-kit/integration/reference/README.md +12 -0
  34. package/knowledge/dapp-kit/integration/reference/glossary.md +190 -0
  35. package/knowledge/dapp-kit/integration/reference/hooks-index.md +190 -0
  36. package/knowledge/dapp-kit/integration/reference/public-api.md +110 -0
  37. package/knowledge/dapp-kit/integration/reference/querykey-conventions.md +179 -0
  38. package/knowledge/dapp-kit/migration/README.md +60 -0
  39. package/knowledge/dapp-kit/migration/ai-rules.md +81 -0
  40. package/knowledge/dapp-kit/migration/breaking-changes/hook-signatures.md +233 -0
  41. package/knowledge/dapp-kit/migration/breaking-changes/querykey-conventions.md +108 -0
  42. package/knowledge/dapp-kit/migration/breaking-changes/result-handling.md +211 -0
  43. package/knowledge/dapp-kit/migration/breaking-changes/sdk-leakage.md +167 -0
  44. package/knowledge/dapp-kit/migration/checklist.md +89 -0
  45. package/knowledge/dapp-kit/migration/features/README.md +34 -0
  46. package/knowledge/dapp-kit/migration/features/auxiliary-services.md +114 -0
  47. package/knowledge/dapp-kit/migration/features/bitcoin.md +88 -0
  48. package/knowledge/dapp-kit/migration/features/bridge.md +160 -0
  49. package/knowledge/dapp-kit/migration/features/dex.md +101 -0
  50. package/knowledge/dapp-kit/migration/features/migration.md +120 -0
  51. package/knowledge/dapp-kit/migration/features/money-market.md +139 -0
  52. package/knowledge/dapp-kit/migration/features/staking.md +109 -0
  53. package/knowledge/dapp-kit/migration/features/swap.md +133 -0
  54. package/knowledge/dapp-kit/migration/recipes.md +185 -0
  55. package/knowledge/dapp-kit/migration/reference/README.md +15 -0
  56. package/knowledge/dapp-kit/migration/reference/deleted-hooks.md +110 -0
  57. package/knowledge/dapp-kit/migration/reference/error-shape-crosswalk.md +144 -0
  58. package/knowledge/dapp-kit/migration/reference/renamed-hooks.md +68 -0
  59. package/knowledge/sdk/AGENTS.md +41 -0
  60. package/knowledge/sdk/integration/README.md +41 -0
  61. package/knowledge/sdk/integration/ai-rules.md +75 -0
  62. package/knowledge/sdk/integration/architecture.md +533 -0
  63. package/knowledge/sdk/integration/chain-specifics.md +189 -0
  64. package/knowledge/sdk/integration/features/README.md +19 -0
  65. package/knowledge/sdk/integration/features/auxiliary-services.md +189 -0
  66. package/knowledge/sdk/integration/features/bridge.md +136 -0
  67. package/knowledge/sdk/integration/features/dex.md +182 -0
  68. package/knowledge/sdk/integration/features/icx-bnusd-baln.md +181 -0
  69. package/knowledge/sdk/integration/features/money-market.md +198 -0
  70. package/knowledge/sdk/integration/features/staking.md +166 -0
  71. package/knowledge/sdk/integration/features/swap.md +207 -0
  72. package/knowledge/sdk/integration/quickstart.md +213 -0
  73. package/knowledge/sdk/integration/recipes/README.md +21 -0
  74. package/knowledge/sdk/integration/recipes/backend-server-init.md +69 -0
  75. package/knowledge/sdk/integration/recipes/chain-key-narrowing.md +65 -0
  76. package/knowledge/sdk/integration/recipes/gas-estimation.md +33 -0
  77. package/knowledge/sdk/integration/recipes/initialize-sodax.md +78 -0
  78. package/knowledge/sdk/integration/recipes/raw-tx-flow.md +71 -0
  79. package/knowledge/sdk/integration/recipes/result-and-errors.md +104 -0
  80. package/knowledge/sdk/integration/recipes/signed-tx-flow.md +46 -0
  81. package/knowledge/sdk/integration/recipes/testing.md +101 -0
  82. package/knowledge/sdk/integration/reference/README.md +18 -0
  83. package/knowledge/sdk/integration/reference/chain-keys.md +67 -0
  84. package/knowledge/sdk/integration/reference/error-codes.md +165 -0
  85. package/knowledge/sdk/integration/reference/glossary.md +32 -0
  86. package/knowledge/sdk/integration/reference/public-api.md +138 -0
  87. package/knowledge/sdk/integration/reference/wallet-providers.md +62 -0
  88. package/knowledge/sdk/migration/README.md +58 -0
  89. package/knowledge/sdk/migration/ai-rules.md +80 -0
  90. package/knowledge/sdk/migration/breaking-changes/architecture.md +344 -0
  91. package/knowledge/sdk/migration/breaking-changes/result-and-errors.md +363 -0
  92. package/knowledge/sdk/migration/breaking-changes/type-system.md +341 -0
  93. package/knowledge/sdk/migration/checklist.md +67 -0
  94. package/knowledge/sdk/migration/features/README.md +35 -0
  95. package/knowledge/sdk/migration/features/auxiliary-services.md +156 -0
  96. package/knowledge/sdk/migration/features/bridge.md +128 -0
  97. package/knowledge/sdk/migration/features/dex.md +143 -0
  98. package/knowledge/sdk/migration/features/icx-bnusd-baln.md +151 -0
  99. package/knowledge/sdk/migration/features/money-market.md +214 -0
  100. package/knowledge/sdk/migration/features/staking.md +138 -0
  101. package/knowledge/sdk/migration/features/swap.md +198 -0
  102. package/knowledge/sdk/migration/recipes.md +350 -0
  103. package/knowledge/sdk/migration/reference/README.md +18 -0
  104. package/knowledge/sdk/migration/reference/deleted-exports.md +127 -0
  105. package/knowledge/sdk/migration/reference/error-code-crosswalk.md +104 -0
  106. package/knowledge/sdk/migration/reference/return-shapes.md +49 -0
  107. package/knowledge/sdk/migration/reference/sodax-config.md +145 -0
  108. package/knowledge/wallet-sdk-core/AGENTS.md +43 -0
  109. package/knowledge/wallet-sdk-core/integration/README.md +108 -0
  110. package/knowledge/wallet-sdk-core/integration/ai-rules.md +141 -0
  111. package/knowledge/wallet-sdk-core/integration/architecture.md +212 -0
  112. package/knowledge/wallet-sdk-core/integration/features/README.md +22 -0
  113. package/knowledge/wallet-sdk-core/integration/features/bitcoin.md +103 -0
  114. package/knowledge/wallet-sdk-core/integration/features/evm.md +102 -0
  115. package/knowledge/wallet-sdk-core/integration/features/icon.md +88 -0
  116. package/knowledge/wallet-sdk-core/integration/features/injective.md +92 -0
  117. package/knowledge/wallet-sdk-core/integration/features/near.md +92 -0
  118. package/knowledge/wallet-sdk-core/integration/features/solana.md +104 -0
  119. package/knowledge/wallet-sdk-core/integration/features/stacks.md +91 -0
  120. package/knowledge/wallet-sdk-core/integration/features/stellar.md +95 -0
  121. package/knowledge/wallet-sdk-core/integration/features/sui.md +96 -0
  122. package/knowledge/wallet-sdk-core/integration/quickstart.md +259 -0
  123. package/knowledge/wallet-sdk-core/integration/recipes/README.md +15 -0
  124. package/knowledge/wallet-sdk-core/integration/recipes/bridge-to-sdk.md +145 -0
  125. package/knowledge/wallet-sdk-core/integration/recipes/defaults-and-overrides.md +159 -0
  126. package/knowledge/wallet-sdk-core/integration/recipes/library-exports.md +129 -0
  127. package/knowledge/wallet-sdk-core/integration/recipes/setup-browser-extension.md +137 -0
  128. package/knowledge/wallet-sdk-core/integration/recipes/setup-private-key.md +115 -0
  129. package/knowledge/wallet-sdk-core/integration/recipes/sign-and-broadcast.md +201 -0
  130. package/knowledge/wallet-sdk-core/integration/recipes/testing.md +163 -0
  131. package/knowledge/wallet-sdk-core/integration/reference/README.md +13 -0
  132. package/knowledge/wallet-sdk-core/integration/reference/chain-support.md +65 -0
  133. package/knowledge/wallet-sdk-core/integration/reference/glossary.md +28 -0
  134. package/knowledge/wallet-sdk-core/integration/reference/interfaces.md +131 -0
  135. package/knowledge/wallet-sdk-core/integration/reference/provider-classes.md +54 -0
  136. package/knowledge/wallet-sdk-core/integration/reference/public-api.md +128 -0
  137. package/knowledge/wallet-sdk-core/migration/README.md +84 -0
  138. package/knowledge/wallet-sdk-core/migration/ai-rules.md +139 -0
  139. package/knowledge/wallet-sdk-core/migration/breaking-changes/README.md +14 -0
  140. package/knowledge/wallet-sdk-core/migration/breaking-changes/base-wallet-provider.md +52 -0
  141. package/knowledge/wallet-sdk-core/migration/breaking-changes/defaults-config.md +57 -0
  142. package/knowledge/wallet-sdk-core/migration/breaking-changes/folder-layout.md +99 -0
  143. package/knowledge/wallet-sdk-core/migration/breaking-changes/library-exports.md +58 -0
  144. package/knowledge/wallet-sdk-core/migration/checklist.md +62 -0
  145. package/knowledge/wallet-sdk-core/migration/recipes/README.md +12 -0
  146. package/knowledge/wallet-sdk-core/migration/recipes/adopt-defaults.md +84 -0
  147. package/knowledge/wallet-sdk-core/migration/recipes/adopt-library-exports.md +99 -0
  148. package/knowledge/wallet-sdk-core/migration/reference/README.md +12 -0
  149. package/knowledge/wallet-sdk-core/migration/reference/added-fields.md +71 -0
  150. package/knowledge/wallet-sdk-core/migration/reference/deleted-exports.md +35 -0
  151. package/knowledge/wallet-sdk-core/migration/reference/renamed-symbols.md +31 -0
  152. package/knowledge/wallet-sdk-core/migration/reference/return-shapes.md +23 -0
  153. package/knowledge/wallet-sdk-react/AGENTS.md +46 -0
  154. package/knowledge/wallet-sdk-react/integration/README.md +103 -0
  155. package/knowledge/wallet-sdk-react/integration/ai-rules.md +136 -0
  156. package/knowledge/wallet-sdk-react/integration/architecture.md +185 -0
  157. package/knowledge/wallet-sdk-react/integration/examples/01-minimal-evm.tsx +75 -0
  158. package/knowledge/wallet-sdk-react/integration/examples/02-multi-chain-modal.tsx +169 -0
  159. package/knowledge/wallet-sdk-react/integration/examples/03-nextjs-app-router.tsx +99 -0
  160. package/knowledge/wallet-sdk-react/integration/examples/04-walletconnect-setup.tsx +89 -0
  161. package/knowledge/wallet-sdk-react/integration/examples/README.md +29 -0
  162. package/knowledge/wallet-sdk-react/integration/recipes/batch-operations.md +224 -0
  163. package/knowledge/wallet-sdk-react/integration/recipes/bridge-to-sdk.md +165 -0
  164. package/knowledge/wallet-sdk-react/integration/recipes/chain-detection.md +259 -0
  165. package/knowledge/wallet-sdk-react/integration/recipes/connect-button.md +159 -0
  166. package/knowledge/wallet-sdk-react/integration/recipes/multi-chain-modal.md +203 -0
  167. package/knowledge/wallet-sdk-react/integration/recipes/setup.md +163 -0
  168. package/knowledge/wallet-sdk-react/integration/recipes/sign-message.md +138 -0
  169. package/knowledge/wallet-sdk-react/integration/recipes/sub-path-imports.md +97 -0
  170. package/knowledge/wallet-sdk-react/integration/recipes/switch-chain.md +144 -0
  171. package/knowledge/wallet-sdk-react/integration/recipes/walletconnect-setup.md +139 -0
  172. package/knowledge/wallet-sdk-react/integration/reference/api-surface.md +176 -0
  173. package/knowledge/wallet-sdk-react/integration/reference/chain-support.md +79 -0
  174. package/knowledge/wallet-sdk-react/integration/reference/connectors.md +75 -0
  175. package/knowledge/wallet-sdk-react/integration/reference/hooks.md +212 -0
  176. package/knowledge/wallet-sdk-react/integration/reference/wallet-brands.md +107 -0
  177. package/knowledge/wallet-sdk-react/migration/README.md +49 -0
  178. package/knowledge/wallet-sdk-react/migration/ai-rules.md +144 -0
  179. package/knowledge/wallet-sdk-react/migration/breaking-changes.md +310 -0
  180. package/knowledge/wallet-sdk-react/migration/checklist.md +159 -0
  181. package/knowledge/wallet-sdk-react/migration/recipes/connect-button.md +170 -0
  182. package/knowledge/wallet-sdk-react/migration/recipes/multi-chain-modal.md +245 -0
  183. package/knowledge/wallet-sdk-react/migration/recipes/ssr-setup.md +165 -0
  184. package/knowledge/wallet-sdk-react/migration/recipes/walletconnect-migration.md +170 -0
  185. package/knowledge/wallet-sdk-react/migration/reference/components.md +75 -0
  186. package/knowledge/wallet-sdk-react/migration/reference/config.md +339 -0
  187. package/knowledge/wallet-sdk-react/migration/reference/hooks.md +336 -0
  188. package/knowledge/wallet-sdk-react/migration/reference/imports.md +158 -0
  189. package/package.json +59 -0
  190. package/skills/sodax-dapp-kit-integration/SKILL.md +71 -0
  191. package/skills/sodax-dapp-kit-migration/SKILL.md +58 -0
  192. package/skills/sodax-sdk-integration/SKILL.md +66 -0
  193. package/skills/sodax-sdk-migration/SKILL.md +75 -0
  194. package/skills/sodax-wallet-sdk-core-integration/SKILL.md +55 -0
  195. package/skills/sodax-wallet-sdk-core-migration/SKILL.md +56 -0
  196. package/skills/sodax-wallet-sdk-react-integration/SKILL.md +80 -0
  197. package/skills/sodax-wallet-sdk-react-migration/SKILL.md +71 -0
@@ -0,0 +1,138 @@
1
+ # Staking migration — v1 → v2
2
+
3
+ Pure-SDK migration playbook for `StakingService`.
4
+
5
+ Pair: [`../../integration/features/staking.md`](../../integration/features/staking.md).
6
+
7
+ ## TL;DR
8
+
9
+ 1. **Drop `spokeProvider` from every params object.** Pass `walletProvider` directly into the SDK call.
10
+ 2. **Add `srcChainKey` + `srcAddress` to every `*Params<K>`.** `account` field is renamed to `srcAddress`.
11
+ 3. **All 5 staking actions are cross-chain.** Even though staking writes happen on the hub, every SDK method (`stake`, `unstake`, `instantUnstake`, `claim`, `cancelUnstake`) accepts `srcChainKey: K extends SpokeChainKey` and relays spoke→hub via `relayTxAndWaitPacket`. **Return shape is always `Result<TxHashPair>`.**
12
+ 4. **`approve` is an exception — it returns `Result<TxReturnType<K, false>>` (single hash).** Approve is spoke-only (no relay) — it just spends ERC20 allowance on the source chain.
13
+ 5. **Approve and allowance are action-discriminated.** `staking.approve` and `staking.isAllowanceValid` take a `StakingParamsUnion` discriminated by `params.action`. `'stake'` approves SODA; `'unstake'` and `'instantUnstake'` approve xSoda.
14
+ 6. **Info getter signatures changed.** v1 took `spokeProvider`; v2 takes `(srcAddress, srcChainKey)`. The SDK derives the hub wallet internally.
15
+ 7. **Hub-only / amount-only reads have no chain context.** `getStakingConfig()`, `getStakeRatio(amount)`, `getInstantUnstakeRatio(amount)`, `getConvertedAssets(amount)` — none accept `srcChainKey`. (Take `bigint` amount directly, not an object.) `getStakeRatio` returns `Result<[xSodaAmount, previewDepositAmount]>` (a tuple — both are bigints).
16
+ 8. **Errors → `SodaxError` + `Result<T>`.** v1's `StakingError<StakingErrorCode>` is gone.
17
+
18
+ ## Type / symbol cheat sheet
19
+
20
+ ### Field-level renames
21
+
22
+ | Type | v1 shape | v2 shape | Notes |
23
+ |---|---|---|---|
24
+ | `StakeParams` | `{ amount, account, minReceive, action: 'stake' }` | `{ srcChainKey, srcAddress, amount, minReceive, action: 'stake' }` | Now generic `<K>`. `account` → `srcAddress`. |
25
+ | `UnstakeParams` | `{ amount, account, action: 'unstake' }` | `{ srcChainKey, srcAddress, amount, action: 'unstake' }` | |
26
+ | `InstantUnstakeParams` | `{ amount, minAmount, account, action: 'instantUnstake' }` | `{ srcChainKey, srcAddress, amount, minAmount, action: 'instantUnstake' }` | |
27
+ | `ClaimParams` | `{ requestId, amount, action: 'claim' }` | `{ srcChainKey, srcAddress, requestId, amount, action: 'claim' }` | Adds chain context. |
28
+ | `CancelUnstakeParams` | `{ requestId, action: 'cancelUnstake' }` | `{ srcChainKey, srcAddress, requestId, action: 'cancelUnstake' }` | Adds chain context. |
29
+ | `getStakingInfo` (read) | `(spokeProvider) => Promise<StakingInfo>` | `(srcAddress, srcChainKey) => Promise<Result<StakingInfo>>` | Renamed to `getStakingInfoFromSpoke` (the v1 `getStakingInfo` was hub-only and is not surfaced now). |
30
+ | `getUnstakingInfo` (read) | `(userAddress, spokeProvider)` | `(srcAddress, srcChainKey)` | v1 ignored `userAddress`; v2 reads it for real. |
31
+ | `getUnstakingInfoWithPenalty` (read) | new (v2) | `(srcAddress, srcChainKey) => Promise<Result<UnstakingInfo & { requestsWithPenalty: UnstakeRequestWithPenalty[] }>>` | Wraps `getUnstakingInfo`'s base shape with a penalty-augmented request list. |
32
+
33
+ ### Deleted symbols
34
+
35
+ - `StakingError<StakingErrorCode>` and `isStakingError` — replaced by `SodaxError<C>` + `feature: 'staking'`.
36
+ - v1 `getStakingInfo(hubAddress, …)` — not exposed as a public method in v2. Use `getStakingInfoFromSpoke(srcAddress, srcChainKey)`; the SDK derives the hub wallet via `HubService.getUserHubWalletAddress` internally.
37
+ - `spokeProvider instanceof SonicSpokeProvider` runtime checks — replace with `isHubChainKeyType(chainKey)` from `@sodax/sdk`.
38
+
39
+ ### v1 → v2 error code crosswalk (staking-specific)
40
+
41
+ | v1 `StakingErrorCode` | v2 code + context |
42
+ |---|---|
43
+ | `STAKE_FAILED` | `EXECUTION_FAILED` (`action: 'stake'`) |
44
+ | `UNSTAKE_FAILED` | `EXECUTION_FAILED` (`action: 'unstake'`) |
45
+ | `INSTANT_UNSTAKE_FAILED` | `EXECUTION_FAILED` (`action: 'instantUnstake'`) |
46
+ | `CLAIM_FAILED` | `EXECUTION_FAILED` (`action: 'claim'`) |
47
+ | `CANCEL_UNSTAKE_FAILED` | `EXECUTION_FAILED` (`action: 'cancelUnstake'`) |
48
+ | `GET_STAKING_INFO_FAILED` | `LOOKUP_FAILED` (`method: 'getStakingInfo'` or `'getStakingInfoFromSpoke'`) |
49
+ | `GET_UNSTAKING_INFO_FAILED` | `LOOKUP_FAILED` (`method: 'getUnstakingInfo'`) |
50
+ | `GET_STAKING_CONFIG_FAILED` | `LOOKUP_FAILED` (`method: 'getStakingConfig'`) |
51
+ | `GET_STAKE_RATIO_FAILED` | `LOOKUP_FAILED` (`method: 'getStakeRatio'`) |
52
+
53
+ ## Per-method delta
54
+
55
+ ### `stake`
56
+
57
+ ```diff
58
+ - await sodax.staking.stake({ amount, account, minReceive, action: 'stake' }, spokeProvider);
59
+ + const result = await sodax.staking.stake({
60
+ + params: {
61
+ + srcChainKey: ChainKeys.ARBITRUM_MAINNET,
62
+ + srcAddress: '0x…',
63
+ + amount, minReceive,
64
+ + action: 'stake',
65
+ + },
66
+ + raw: false,
67
+ + walletProvider,
68
+ + });
69
+ + if (!result.ok) return;
70
+ + const { srcChainTxHash, dstChainTxHash } = result.value;
71
+ ```
72
+
73
+ ### `unstake` / `instantUnstake` / `claim` / `cancelUnstake`
74
+
75
+ Same shape as stake. `account` → `srcAddress`. `requestId` (claim, cancelUnstake) is unchanged.
76
+
77
+ ### `approve` / `isAllowanceValid` — action-discriminated
78
+
79
+ ```diff
80
+ - await sodax.staking.approveStake({ amount, account, ... }, spokeProvider);
81
+ + await sodax.staking.approve({
82
+ + params: { srcChainKey, srcAddress, amount, action: 'stake' },
83
+ + raw: false,
84
+ + walletProvider,
85
+ + });
86
+ ```
87
+
88
+ For `isAllowanceValid`:
89
+
90
+ ```ts
91
+ const result = await sodax.staking.isAllowanceValid({
92
+ params: { srcChainKey, srcAddress, amount, action: 'stake' },
93
+ raw: true, // read-only
94
+ });
95
+ ```
96
+
97
+ ### Info reads
98
+
99
+ ```diff
100
+ - const info = await sodax.staking.getStakingInfo(spokeProvider);
101
+ + const result = await sodax.staking.getStakingInfoFromSpoke(srcAddress, srcChainKey);
102
+ + if (!result.ok) return;
103
+ + const info = result.value;
104
+ ```
105
+
106
+ For amount-only reads (no chain context):
107
+
108
+ ```ts
109
+ const result = await sodax.staking.getStakeRatio(parseUnits('100', 18));
110
+ if (result.ok) {
111
+ const [xSodaAmount, previewDepositAmount] = result.value;
112
+ }
113
+ ```
114
+
115
+ ## Pitfalls
116
+
117
+ Cross-cutting traps (Result destructuring, error-model migration, srcChain/dstChain renames, etc.) live in [`../ai-rules.md`](../ai-rules.md). The list below is feature-specific — typecheck fingerprints, return-shape diffs, and gotchas unique to this feature.
118
+
119
+ 1. **Wrong return shape for actions.** Treating `stake/unstake/etc.` as returning `Result<TxReturnType<K, false>>` (single hash) is **wrong** — they return `Result<TxHashPair>` because they always relay spoke→hub. Only `approve` returns a single hash.
120
+ 2. **Forgetting `raw: true` on the allowance query.** TypeScript error: `Property 'walletProvider' is missing`. `isAllowanceValid` requires `WalletProviderSlot<K, Raw>`; `raw: false` would force a wallet provider. Use `raw: true` for read-only.
121
+ 3. **Forgetting to remove the v1 `account` field from params.** v2 uses `srcAddress`. If both are set, TypeScript rejects the literal.
122
+ 4. **`getStakingInfo(hubAddress)` is not a public method in v2.** v1 had it for direct hub queries. v2 has `getStakingInfoFromSpoke(srcAddress, srcChainKey)` which derives the hub wallet internally. Use the spoke variant.
123
+ 5. **`UnstakingInfo` no longer accepts `userAddress` separately.** v1 took both `spokeProvider` and `userAddress` props but ignored `userAddress` inside. v2 takes `srcAddress` and uses it.
124
+
125
+ ## Verification
126
+
127
+ ```bash
128
+ pnpm -C <your-app-dir> checkTs
129
+
130
+ # Targeted scans:
131
+ grep -rE "spokeProvider:\s*\w+|account:\s*[`'][^`']+['\"`]" src/ # leftover v1 patterns
132
+ grep -rE "isStakingError\b|StakingError\b" src/
133
+ ```
134
+
135
+ ## Cross-references
136
+
137
+ - v2 staking usage: [`../../integration/features/staking.md`](../../integration/features/staking.md).
138
+ - Cross-cutting prerequisites listed in [`../README.md`](../README.md).
@@ -0,0 +1,198 @@
1
+ # Swap migration — v1 → v2
2
+
3
+ Pure-SDK migration playbook for `SwapService`.
4
+
5
+ Pair: [`../../integration/features/swap.md`](../../integration/features/swap.md).
6
+
7
+ ## TL;DR
8
+
9
+ 1. **Drop the `*SpokeProvider` argument.** Pass `walletProvider` directly into the SDK call payload alongside `params` and `raw: false`.
10
+ 2. **Add `raw: false` (or `raw: true`) to every call shape.** Without it, TypeScript can't pick a branch of `WalletProviderSlot` and rejects `walletProvider`.
11
+ 3. **Field renames on `CreateIntentParams<K>` and `CreateLimitOrderParams<K>`:**
12
+ - `srcChain` → `srcChainKey`
13
+ - `dstChain` → `dstChainKey`
14
+ - **`Intent.srcChain` / `Intent.dstChain` are unchanged** (read shape) — they're `IntentRelayChainId` (bigint).
15
+ 4. **`CreateIntentResult` shape changed.** v1 was a tuple `[spokeTxHash, intent, relayData]`; v2 is an object `{ tx, intent, relayData }`. Destructure accordingly.
16
+ 5. **`SubmitSwapTxRequest.srcChainId` → `srcChainKey`.** And `relayData` field on the request expects a **string** (`relayData.payload`), not the `RelayExtraData` object.
17
+ 6. **Errors → `SodaxError` + `Result<T>`.** v1's `IntentError<IntentErrorCode>` is gone. Branch on `result.ok`; use `(error.feature, error.code)` for discrimination.
18
+
19
+ ## Type / symbol cheat sheet
20
+
21
+ ### Field-level renames
22
+
23
+ | Type | v1 field | v2 field | Notes |
24
+ |---|---|---|---|
25
+ | `CreateIntentParams` (request) | `srcChain`, `dstChain` | `srcChainKey`, `dstChainKey` | Now generic: `CreateIntentParams<K extends SpokeChainKey>`. |
26
+ | `CreateLimitOrderParams` (request) | `srcChain`, `dstChain` | `srcChainKey`, `dstChainKey` | `Omit<CreateIntentParams<K>, 'deadline'>`. |
27
+ | `SubmitSwapTxRequest` (backend req) | `srcChainId` | `srcChainKey` | And `relayData: string` (was the object in v1). |
28
+ | `Intent` (read shape) | `srcChain`, `dstChain` | **unchanged** | `IntentRelayChainId` (bigint). Don't grep-replace blindly. |
29
+ | `XToken` | `xChainId` | `chainKey` | Type renamed from `Token` → `XToken`. |
30
+ | `CreateIntentResult` | tuple `[spokeTxHash, intent, relayData]` | object `{ tx, intent, relayData }` | Generic: `CreateIntentResult<K, Raw>`. |
31
+
32
+ ### Deleted symbols
33
+
34
+ - The `SpokeProvider` union and per-chain `*SpokeProvider` classes — gone. v2 takes `walletProvider` directly. See [`../breaking-changes/architecture.md`](../breaking-changes/architecture.md) § 1.
35
+ - `IntentError<IntentErrorCode>` and `isIntentError` / `isIntentPostExecutionFailedError` / `isIntentSubmitTxFailedError` type guards. Replaced by `isSodaxError` + feature/code discrimination.
36
+ - `CustomProvider` (Hana wallet window typedecl) — declare `unknown` or import directly from the wallet vendor.
37
+ - `hubAssets` global — gone. `XToken.vault` and `XToken.hubAsset` baked in.
38
+
39
+ ### v1 → v2 error code crosswalk (swap-specific)
40
+
41
+ | v1 `IntentErrorCode` | v2 `SodaxErrorCode` + context |
42
+ |---|---|
43
+ | `CREATE_INTENT_FAILED` | `INTENT_CREATION_FAILED` (`action: 'createIntent'`) |
44
+ | `CREATE_LIMIT_ORDER_FAILED` | `INTENT_CREATION_FAILED` (`action: 'createLimitOrder'`) |
45
+ | `POST_EXECUTION_FAILED` | `EXECUTION_FAILED` (`action: 'swap'`, `phase: 'postExecution'`) |
46
+ | `SOLVER_API_ERROR` | `EXTERNAL_API_ERROR` (`api: 'solver'`, with `solverCode`/`solverDetail` on context) |
47
+ | `SIMULATION_FAILED` | `EXECUTION_FAILED` (`phase: 'execution'`) |
48
+ | `SUBMIT_TX_FAILED` (relay) | `TX_SUBMIT_FAILED` (`relayCode: 'SUBMIT_TX_FAILED'`) |
49
+ | `RELAY_TIMEOUT` | `RELAY_TIMEOUT` (unchanged code; still on `relayCode`) |
50
+
51
+ ## Per-method delta
52
+
53
+ ### `swap`
54
+
55
+ ```diff
56
+ - await sodax.swaps.swap({
57
+ - intentParams,
58
+ - spokeProvider: sourceSpokeProvider,
59
+ - });
60
+ + const result = await sodax.swaps.swap({
61
+ + params: intentParams,
62
+ + raw: false,
63
+ + walletProvider: sourceWalletProvider,
64
+ + });
65
+ + if (!result.ok) return;
66
+ + const { spokeTxHash, intent, relayData } = result.value;
67
+ ```
68
+
69
+ ### `createIntent`
70
+
71
+ ```diff
72
+ - const [spokeTxHash, intent, relayData] = await sodax.swaps.createIntent({
73
+ - intentParams,
74
+ - spokeProvider: sourceSpokeProvider,
75
+ - });
76
+ + const result = await sodax.swaps.createIntent({
77
+ + params: intentParams,
78
+ + raw: false,
79
+ + walletProvider: sourceWalletProvider,
80
+ + });
81
+ + if (!result.ok) return;
82
+ + const { tx: spokeTxHash, intent, relayData } = result.value;
83
+ ```
84
+
85
+ ### `createLimitOrder`
86
+
87
+ Same as `createIntent` shape (with `CreateLimitOrderParams`). v1 took `{ limitOrderParams, spokeProvider }`; v2 takes `{ params, raw: false, walletProvider }`.
88
+
89
+ ### `cancelIntent` / `cancelLimitOrder`
90
+
91
+ ```diff
92
+ - await sodax.swaps.cancelIntent({ srcChain, intent, spokeProvider });
93
+ + await sodax.swaps.cancelIntent({
94
+ + params: { srcChainKey, intent },
95
+ + raw: false,
96
+ + walletProvider,
97
+ + });
98
+ ```
99
+
100
+ ### `approve` / `isAllowanceValid`
101
+
102
+ v1: `await sodax.swaps.approve({ intentParams, spokeProvider })`.
103
+ v2: `await sodax.swaps.approve({ params: intentParams, raw: false, walletProvider })`.
104
+
105
+ For `isAllowanceValid` in **read-only** flows (e.g. UI polling), use `raw: true` to skip the wallet-provider requirement:
106
+
107
+ ```ts
108
+ const result = await sodax.swaps.isAllowanceValid({ params, raw: true });
109
+ ```
110
+
111
+ The underlying read doesn't consult the wallet provider; `raw: true` is the contract for read-only access.
112
+
113
+ ### Backend submit-tx (`SubmitSwapTxRequest`)
114
+
115
+ ```diff
116
+ const request: SubmitSwapTxRequest = {
117
+ txHash: spokeTxHash as string,
118
+ - srcChainId: sourceChain,
119
+ + srcChainKey: src.chain,
120
+ walletAddress: sourceAccount.address ?? '',
121
+ intent: swapIntentData,
122
+ - relayData, // was the RelayExtraData object
123
+ + relayData: relayData.payload, // now a string
124
+ };
125
+ const submitResult = await sodax.backendApi.submitSwapTx(request);
126
+ if (!submitResult.ok) return;
127
+ ```
128
+
129
+ ## Worked example — `handleSubmitTxSwap` flow
130
+
131
+ ```diff
132
+ const handleSubmitTxSwap = async (intentOrderPayload: CreateIntentParams) => {
133
+ - if (!sourceProvider) return;
134
+ + if (!sourceWalletProvider) return;
135
+ - const createIntentResult = await sodax.swaps.createIntent({
136
+ - intentParams: intentOrderPayload,
137
+ - spokeProvider: sourceProvider,
138
+ - });
139
+ + const createIntentResult = await sodax.swaps.createIntent({
140
+ + params: intentOrderPayload,
141
+ + raw: false,
142
+ + walletProvider: sourceWalletProvider,
143
+ + });
144
+ if (!createIntentResult.ok) return;
145
+ - const [spokeTxHash, intent, relayData] = createIntentResult.value;
146
+ + const { tx: spokeTxHash, intent, relayData } = createIntentResult.value;
147
+ const swapIntentData: SwapIntentData = {
148
+ /* … */
149
+ - srcChain: Number(intent.srcChain), // Intent.srcChain still on read shape
150
+ - dstChain: Number(intent.dstChain), // Intent.dstChain still on read shape
151
+ + srcChain: Number(intent.srcChain), // unchanged — Intent shape kept these
152
+ + dstChain: Number(intent.dstChain),
153
+ };
154
+ const request: SubmitSwapTxRequest = {
155
+ txHash: spokeTxHash as string,
156
+ - srcChainId: sourceChain,
157
+ + srcChainKey: src.chain,
158
+ walletAddress: sourceAccount.address ?? '',
159
+ intent: swapIntentData,
160
+ - relayData,
161
+ + relayData: relayData.payload,
162
+ };
163
+ - await submitSwapTx(request);
164
+ + const submitResult = await sodax.backendApi.submitSwapTx(request);
165
+ + if (!submitResult.ok) return;
166
+ };
167
+ ```
168
+
169
+ ## Pitfalls
170
+
171
+ Cross-cutting traps (Result destructuring, error-model migration, srcChain/dstChain renames, etc.) live in [`../ai-rules.md`](../ai-rules.md). The list below is feature-specific — typecheck fingerprints, return-shape diffs, and gotchas unique to this feature.
172
+
173
+ 1. **Over-broad regex on `srcChain` / `dstChain`.** Request types renamed; `Intent` (read shape) didn't. Distinguish "I'm building a request" from "I'm reading an intent."
174
+ 2. **`createIntent` success shape changed from tuple to object.** `{ tx, intent, relayData }`, not `[spokeTxHash, intent, relayData]`.
175
+ 3. **`relayData` on `SubmitSwapTxRequest` is a `string`.** It's `relayData.payload`, not the full `RelayExtraData` object.
176
+ 4. **`spokeTxHash` is `TxReturnType<K, false>`, not necessarily `string`.** For most chains it's a string already, but the SDK type is broader. Cast at the boundary when passing to APIs that strictly want `string`: `txHash: spokeTxHash as string`.
177
+ 5. **`Intent.deadline` is `bigint`.** `Math.floor(Date.now() / 1000) + 60 * 5` returns a number; wrap in `BigInt(...)`.
178
+ 6. **`IntentResponse.srcChain` / `dstChain` from the backend are `IntentRelayChainId` (number/bigint), not chain keys.** Convert via `sodax.config.getSpokeChainKeyFromIntentRelayChainId(BigInt(intent.dstChain))` when displaying.
179
+ 7. **`hubAssets` is gone.** Anything that walked `hubAssets[chainId]` for vault lookup must use `XToken.vault` (now baked in) or `sodax.config.getOriginalAssetAddress()`.
180
+ 8. **`SodaxConfig.swaps` vs `.solver`.** v1 mixed solver endpoints under `swaps`; v2 splits — `swaps` for supported tokens, `solver` for endpoints. See [`../breaking-changes/architecture.md`](../breaking-changes/architecture.md) Appendix B.
181
+
182
+ ## Verification
183
+
184
+ After migrating swap call sites:
185
+
186
+ ```bash
187
+ # Should produce zero errors when the migration is complete:
188
+ pnpm -C <your-app-dir> checkTs
189
+
190
+ # Targeted scan for leftover v1 patterns:
191
+ grep -rE "spokeProvider:\s*\w+|intentParams:\s*\w+|srcChain:\s*\w+\.[a-z]+ChainId" src/
192
+ grep -rE "isIntentError\b|isIntentPostExecutionFailedError\b|isIntentSubmitTxFailedError\b" src/
193
+ ```
194
+
195
+ ## Cross-references
196
+
197
+ - v2 swap usage: [`../../integration/features/swap.md`](../../integration/features/swap.md).
198
+ - Cross-cutting prerequisites (type-system, architecture, result/errors) listed in [`../README.md`](../README.md).