@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,341 @@
1
+ # Type-system breaking changes — v1 → v2
2
+
3
+ Every type-level rename and shape change introduced by v2. Fix these first — once your imports compile, every other migration step is tractable. The errors you'll see during this phase live in three buckets: **import resolution** (a symbol moved or was deleted), **field access** (a field renamed), and **shape mismatch** (a generic added a required parameter, a return type changed).
4
+
5
+ > v1 source the comparisons below cite: `github.com/icon-project/sodax-frontend` (branch `sdk-v1-main`), `packages/sdk` and `packages/types`. v2 source: this package's `src/`.
6
+
7
+ ## Section index
8
+
9
+ 1. [Chain identifiers](#1-chain-identifiers) — `*_MAINNET_CHAIN_ID` → `ChainKeys.*`. The single biggest mechanical migration.
10
+ 2. [`@sodax/types` package surface](#2-sodaxtypes-package-surface) — what to import, what got renamed, what got deleted.
11
+ 3. [Wallet-provider typing](#3-wallet-provider-typing) — `GetWalletProviderType<K>` and `WalletProviderSlot<K, Raw>` replace ad-hoc spoke-provider classes.
12
+ 4. [`Token` / `XToken` field renames](#4-token--xtoken-field-renames) — `xChainId` → `chainKey`; `Token` → `XToken`.
13
+ 5. [`RpcConfig` reshape](#5-rpcconfig-reshape) — now keyed by `ChainKey` values; chain-family-specific shapes for Bitcoin and Stellar.
14
+ 6. [`IConfigApi` Result-wrapping](#6-iconfigapi-result-wrapping) — every method returns `Promise<Result<T>>`.
15
+ 7. [Address-type rename](#7-address-type-rename) — `AddressType` → `BtcAddressType`.
16
+ 8. [Wallet-provider `chainType` discriminant](#8-wallet-provider-chaintype-discriminant) — every `I*WalletProvider` declares a literal field.
17
+ 9. [`ChainId` / `SpokeChainId` → `SpokeChainKey`](#9-chainid--spokechainid--spokechainkey) — type alias rename.
18
+ 10. [Deleted module-error types](#10-deleted-module-error-types) — covered structurally here, semantics in [`result-and-errors.md`](result-and-errors.md).
19
+
20
+ ---
21
+
22
+ ## 1. Chain identifiers
23
+
24
+ v1 exported one constant per chain (`SONIC_MAINNET_CHAIN_ID`, `ARBITRUM_MAINNET_CHAIN_ID`, …). v2 collapses them into a single `ChainKeys` object whose values are the same string union exposed as the `ChainKey` type. The constants and their old union (`SpokeChainId` / `ChainId`) are deleted.
25
+
26
+ ### Import migration
27
+
28
+ ```diff
29
+ - import {
30
+ - SONIC_MAINNET_CHAIN_ID,
31
+ - ARBITRUM_MAINNET_CHAIN_ID,
32
+ - AVALANCHE_MAINNET_CHAIN_ID,
33
+ - // ...
34
+ - } from '@sodax/types';
35
+ + import { ChainKeys } from '@sodax/sdk'; // re-exported from @sodax/types
36
+ ```
37
+
38
+ > Prefer importing `ChainKeys` from `@sodax/sdk` — see [§2](#2-sodaxtypes-package-surface). Importing from `@sodax/types` still works but adds an unnecessary peer dependency.
39
+
40
+ ### Full mapping table
41
+
42
+ | v1 constant | v2 `ChainKeys.*` | String value |
43
+ |---|---|---|
44
+ | `SONIC_MAINNET_CHAIN_ID` | `ChainKeys.SONIC_MAINNET` | `'sonic'` |
45
+ | `ARBITRUM_MAINNET_CHAIN_ID` | `ChainKeys.ARBITRUM_MAINNET` | `'0xa4b1.arbitrum'` |
46
+ | `AVALANCHE_MAINNET_CHAIN_ID` | `ChainKeys.AVALANCHE_MAINNET` | `'0xa86a.avax'` |
47
+ | `BASE_MAINNET_CHAIN_ID` | `ChainKeys.BASE_MAINNET` | `'0x2105.base'` |
48
+ | `BSC_MAINNET_CHAIN_ID` | `ChainKeys.BSC_MAINNET` | `'0x38.bsc'` |
49
+ | `ETHEREUM_MAINNET_CHAIN_ID` | `ChainKeys.ETHEREUM_MAINNET` | `'ethereum'` |
50
+ | `HYPEREVM_MAINNET_CHAIN_ID` | `ChainKeys.HYPEREVM_MAINNET` | `'hyper'` |
51
+ | `ICON_MAINNET_CHAIN_ID` | `ChainKeys.ICON_MAINNET` | `'0x1.icon'` |
52
+ | `INJECTIVE_MAINNET_CHAIN_ID` | `ChainKeys.INJECTIVE_MAINNET` | `'injective-1'` |
53
+ | `KAIA_MAINNET_CHAIN_ID` | `ChainKeys.KAIA_MAINNET` | `'0x2019.kaia'` |
54
+ | `LIGHTLINK_MAINNET_CHAIN_ID` | `ChainKeys.LIGHTLINK_MAINNET` | `'lightlink'` |
55
+ | `NEAR_MAINNET_CHAIN_ID` | `ChainKeys.NEAR_MAINNET` | `'near'` |
56
+ | `OPTIMISM_MAINNET_CHAIN_ID` | `ChainKeys.OPTIMISM_MAINNET` | `'0xa.optimism'` |
57
+ | `POLYGON_MAINNET_CHAIN_ID` | `ChainKeys.POLYGON_MAINNET` | `'0x89.polygon'` |
58
+ | `REDBELLY_MAINNET_CHAIN_ID` | `ChainKeys.REDBELLY_MAINNET` | `'redbelly'` |
59
+ | `SOLANA_MAINNET_CHAIN_ID` | `ChainKeys.SOLANA_MAINNET` | `'solana'` |
60
+ | `STACKS_MAINNET_CHAIN_ID` | `ChainKeys.STACKS_MAINNET` | `'stacks'` |
61
+ | `STELLAR_MAINNET_CHAIN_ID` | `ChainKeys.STELLAR_MAINNET` | `'stellar'` |
62
+ | `SUI_MAINNET_CHAIN_ID` | `ChainKeys.SUI_MAINNET` | `'sui'` |
63
+ | `BITCOIN_MAINNET_CHAIN_ID` | `ChainKeys.BITCOIN_MAINNET` | `'bitcoin'` |
64
+
65
+ ### Bulk codemod
66
+
67
+ ```bash
68
+ # Find — preserves capture group
69
+ grep -rE '(\w+)_MAINNET_CHAIN_ID' src/
70
+
71
+ # Sed (one-shot)
72
+ find src -type f -name '*.ts' -o -name '*.tsx' | xargs sed -i '' -E 's/([A-Z_]+)_MAINNET_CHAIN_ID/ChainKeys.\1_MAINNET/g'
73
+ ```
74
+
75
+ After replacement, fix import statements: remove the individual constants, add `ChainKeys`. See [`../recipes.md`](../recipes.md) § "Codemod patterns" for a more robust `ts-morph` variant.
76
+
77
+ ### Pitfalls
78
+
79
+ 1. **`ChainKeys.ICON_MAINNET` is a string `'0x1.icon'`, not the legacy numeric ID.** Anywhere v1 did `Number(chainId)` for ICON, the v2 result is `NaN`. Use string equality (`chainKey === ChainKeys.ICON_MAINNET`) and audit numeric coercions.
80
+ 2. **`SONIC_MAINNET` is `'sonic'`, not `'0x92.sonic'`** — it's the simple string `'sonic'` because Sonic is the hub chain and treated specially by routing.
81
+ 3. **Don't confuse `ChainKey` with relay chain IDs.** Read shapes like `Intent.srcChain` and `Intent.dstChain` are still `IntentRelayChainId` (bigint) — those did **not** rename. A blanket `srcChain` → `srcChainKey` grep-replace will break Intent reads. Use `sodax.config.getSpokeChainKeyFromIntentRelayChainId(...)` to convert.
82
+
83
+ ---
84
+
85
+ ## 2. `@sodax/types` package surface
86
+
87
+ ### Export reorganization
88
+
89
+ v1 had a single `packages/types/src/constants/index.ts` barrel exporting all chain IDs and ad-hoc tables. That file is **deleted**. Symbols now live in domain-organized modules: `chains/`, `swap/`, `wallet/`, `bitcoin/`, etc.
90
+
91
+ | v1 import path | v2 home |
92
+ |---|---|
93
+ | `@sodax/types/btc/...` | `@sodax/types/bitcoin` (path renamed) |
94
+ | `*_MAINNET_CHAIN_ID` from `@sodax/types` constants index | `ChainKeys.*` (single barrel) |
95
+ | `Token` | `XToken` (renamed; see [§4](#4-token--xtoken-field-renames)) |
96
+ | `SpokeChainId` / `ChainId` | `SpokeChainKey` (see [§9](#9-chainid--spokechainid--spokechainkey)) |
97
+
98
+ ### Re-export from `@sodax/sdk`
99
+
100
+ `@sodax/sdk` v2 barrel re-exports the entire `@sodax/types` surface (`export * from '@sodax/types'` from `src/index.ts`). For consumers, this means:
101
+
102
+ - **Recommended:** import everything from `@sodax/sdk`. You don't need a separate `@sodax/types` dependency.
103
+ - **Tolerated:** keep importing from `@sodax/types` directly. v2 guarantees type identity (since SDK bundles `@sodax/types` via `noExternal`), but you'll pin two versions instead of one.
104
+
105
+ ### Pitfall
106
+
107
+ If your `package.json` lists `@sodax/types` as a direct dependency in v2, **remove it**. Letting it float independent of `@sodax/sdk` invites silent version skew on the next minor bump.
108
+
109
+ ---
110
+
111
+ ## 3. Wallet-provider typing
112
+
113
+ v1 modeled "the wallet to use for chain X" as a class instance: `EvmSpokeProvider`, `SolanaSpokeProvider`, etc. Consumers constructed one and passed it positionally to every SDK call. v2 deletes these classes (see [`architecture.md`](architecture.md) § "Spoke-provider deletion") and replaces the typing with two parameterised aliases:
114
+
115
+ ```ts
116
+ GetChainType<K extends ChainKey> // 'EVM' | 'BITCOIN' | 'SOLANA' | …
117
+ GetWalletProviderType<K extends ChainKey> // IEvmWalletProvider | IBitcoinWalletProvider | …
118
+ ```
119
+
120
+ When the caller passes a literal chain key (e.g. `ChainKeys.ETHEREUM_MAINNET`), TypeScript preserves the literal in the generic `K`. From that one literal:
121
+
122
+ - `GetChainType<K>` resolves to `'EVM'`.
123
+ - `GetWalletProviderType<K>` resolves to `IEvmWalletProvider` (the exact interface, not a broad union).
124
+
125
+ This is what allows v2 to demand the chain-correct wallet provider at compile time without a runtime check.
126
+
127
+ ### `WalletProviderSlot<K, Raw>` — the discriminator
128
+
129
+ ```ts
130
+ // Conceptual; lives in @sodax/types/common
131
+ export type WalletProviderSlot<K extends ChainKey, Raw extends boolean> =
132
+ Raw extends true
133
+ ? { raw: true; walletProvider?: never }
134
+ : { raw: false; walletProvider: GetWalletProviderType<K> };
135
+ ```
136
+
137
+ Three rules enforced at compile time:
138
+
139
+ 1. **`raw: true`** — `walletProvider` is **forbidden** (`?: never` rejects any value). The method returns a raw, unsigned tx payload. Use for sign-elsewhere flows.
140
+ 2. **`raw: false`** — `walletProvider` is **required** and chain-narrowed. The method signs and broadcasts; returns a tx hash.
141
+ 3. **No overlap** — TypeScript can't pick a branch unless the discriminator field is present. Forgetting `raw: false` is the #1 v2 typecheck error after migration.
142
+
143
+ ### Migration mechanics
144
+
145
+ ```diff
146
+ await sodax.swaps.createIntent({
147
+ - intentParams,
148
+ - spokeProvider: sourceProvider,
149
+ + params: intentParams,
150
+ + raw: false,
151
+ + walletProvider: sourceWalletProvider,
152
+ });
153
+ ```
154
+
155
+ For raw-tx building:
156
+
157
+ ```diff
158
+ - // v1 had a separate executeXxx method per chain
159
+ - const tx = await sourceProvider.executeCreateIntent(intentParams);
160
+ + const result = await sodax.swaps.createIntent({ params: intentParams, raw: true });
161
+ + // result.value: { tx: EvmRawTransaction | SolanaRawTransaction | ..., intent, relayData }
162
+ ```
163
+
164
+ ### Pitfall
165
+
166
+ If your wallet provider variable is typed as the broad `IWalletProvider | undefined` union (the typical case when the variable is keyed by a runtime chain-key value rather than a literal), v2 still accepts it — `K` defaults to the broad `SpokeChainKey` union, so `GetWalletProviderType<K>` resolves to the `IWalletProvider` union. For tighter narrowing on a literal chain branch, see [`../recipes.md`](../recipes.md) § "Cast-at-boundary".
167
+
168
+ ---
169
+
170
+ ## 4. `Token` / `XToken` field renames
171
+
172
+ | v1 | v2 |
173
+ |---|---|
174
+ | `Token` (type name) | `XToken` |
175
+ | `Token.xChainId` | `XToken.chainKey` |
176
+ | `Token.symbol`, `decimals`, `address`, `name` | unchanged |
177
+ | (n/a) | `XToken.vault` — added; the hub-side ERC4626 vault for this token |
178
+ | (n/a) | `XToken.hubAsset` — added; the hub-side wrapped/unified asset address |
179
+
180
+ Migration:
181
+
182
+ ```diff
183
+ - import type { Token } from '@sodax/types';
184
+ + import type { XToken } from '@sodax/sdk';
185
+ - token.xChainId
186
+ + token.chainKey
187
+ ```
188
+
189
+ ### Why `vault` / `hubAsset` matter
190
+
191
+ v1 consumers reached into a global `hubAssets[chainId][address]` map to get the vault address for a token. **v2 deletes that global** and bakes the data directly into every supported `XToken`. Anywhere v1 walked `hubAssets`, v2 reads `token.vault` or `token.hubAsset` directly. See [`architecture.md`](architecture.md) § "ConfigService replaces static lookups" for the full lookup migration.
192
+
193
+ ### Pitfall
194
+
195
+ Read shapes like `Intent` and `IntentResponse` from the backend keep `srcChain` / `dstChain` as the **relay** chain id (numeric, `IntentRelayChainId`). They are **not** chain keys and were **not** renamed to `srcChainKey`/`dstChainKey`. Only **request** types (`CreateIntentParams`, `CreateLimitOrderParams`, `SubmitSwapTxRequest`) gained the `*ChainKey` field names.
196
+
197
+ ### Exception — partner module read shapes DID rename
198
+
199
+ The above "read shapes keep `srcChain`/`dstChain`" rule has one exception: **partner module** read shapes also renamed `dstChain` → `dstChainKey`. Specifically:
200
+
201
+ - `AutoSwapPreferences` (returned by `sodax.partners.getAutoSwapPreferences(queryAddress)`) — field `dstChain` → **`dstChainKey: SpokeChainKey | 'not configured'`**.
202
+ - `SetSwapPreferenceParams` (request type for `setSwapPreference`) — `dstChain` → `dstChainKey: SpokeChainKey`.
203
+
204
+ ```diff
205
+ - // v1
206
+ - const prefs = await partnerFeeClaimService.getAutoSwapPreferences(addr);
207
+ - const destChain: SpokeChainId = prefs.dstChain;
208
+
209
+ + // v2
210
+ + const result = await sodax.partners.getAutoSwapPreferences(addr);
211
+ + if (!result.ok) return;
212
+ + const destChain: SpokeChainKey | 'not configured' = result.value.dstChainKey;
213
+ ```
214
+
215
+ A blanket grep `dstChain` → `dstChainKey` is safe in the partner module **but** still unsafe in `Intent` / `IntentResponse` reads. Scope grep replacements per file or per import. The general rule for `srcChain` (Intent read field) is unchanged: it remains the relay chain id.
216
+
217
+ ---
218
+
219
+ ## 5. `RpcConfig` reshape
220
+
221
+ v1 modeled `RpcConfig` as a flat object with one optional URL field per chain. v2 makes it a mapped type keyed by `ChainKey` values, with chain-family-specific shapes:
222
+
223
+ ```ts
224
+ type RpcConfig = {
225
+ [K in ChainKey]:
226
+ K extends typeof ChainKeys.BITCOIN_MAINNET ? BitcoinRpcConfig :
227
+ K extends typeof ChainKeys.STELLAR_MAINNET ? StellarRpcConfig :
228
+ string // RPC URL for every other chain
229
+ };
230
+ ```
231
+
232
+ Migration:
233
+
234
+ ```diff
235
+ - rpcConfig.sonic
236
+ + rpcConfig[ChainKeys.SONIC_MAINNET]
237
+ - rpcConfig.btc
238
+ + rpcConfig[ChainKeys.BITCOIN_MAINNET] // BitcoinRpcConfig (shape, not string)
239
+ ```
240
+
241
+ ### Pitfall
242
+
243
+ Bitcoin and Stellar have richer RPC needs than other chains (multiple endpoints, network params). Their entries in `RpcConfig` are objects, not strings. If your config builder did `rpcConfig.btc = 'https://…'` in v1, that's a type error in v2 — you need the full `BitcoinRpcConfig` shape.
244
+
245
+ ---
246
+
247
+ ## 6. `IConfigApi` Result-wrapping
248
+
249
+ Every method on the `IConfigApi` contract changed signature in v2. v1 returned plain `Promise<T>` and threw on failure; v2 returns `Promise<Result<T>>` and never throws.
250
+
251
+ | Method | v1 return | v2 return |
252
+ |---|---|---|
253
+ | `getChains` | `Promise<ChainConfig[]>` | `Promise<Result<GetChainsApiResponse>>` |
254
+ | `getSwapTokens` | `Promise<SwapTokenConfig>` | `Promise<Result<GetSwapTokensApiResponse>>` |
255
+ | `getSwapTokensByChainId` | `Promise<XToken[]>` | `Promise<Result<XToken[]>>` |
256
+ | `getMoneyMarketTokens` | `Promise<MMTokenConfig>` | `Promise<Result<GetMoneyMarketTokensApiResponse>>` |
257
+ | `getMoneyMarketTokensByChainId` | `Promise<XToken[]>` | `Promise<Result<XToken[]>>` |
258
+ | `getRelayChainIdMap` | (n/a in v1) | `Promise<Result<GetRelayChainIdMapApiResponse>>` (v2-new) |
259
+
260
+ If you implemented a custom `IConfigApi` (e.g. for a sandbox or test fixture), update every method signature. If you only consumed the default implementation through `Sodax.config`, the SDK already uses `Result` internally — your consumer-side code doesn't see the wrapping.
261
+
262
+ ---
263
+
264
+ ## 7. Address-type rename
265
+
266
+ The Bitcoin-specific address-type union changed name to free up the generic `AddressType` identifier:
267
+
268
+ ```diff
269
+ - import type { AddressType } from '@sodax/types';
270
+ + import type { BtcAddressType } from '@sodax/sdk';
271
+ ```
272
+
273
+ Value union is unchanged: `'P2PKH' | 'P2SH' | 'P2WPKH' | 'P2TR'`. Custom Bitcoin wallet provider implementations must update the import.
274
+
275
+ ---
276
+
277
+ ## 8. Wallet-provider `chainType` discriminant
278
+
279
+ Every `I*WalletProvider` interface in v2 declares a `readonly chainType: '<CHAIN>'` literal field. Custom implementations must add the field; consumers can use it for runtime narrowing without `instanceof`:
280
+
281
+ ```ts
282
+ if (walletProvider.chainType === 'EVM') {
283
+ // walletProvider: IEvmWalletProvider
284
+ }
285
+ if (walletProvider.chainType === 'SOLANA') {
286
+ // walletProvider: ISolanaWalletProvider
287
+ }
288
+ ```
289
+
290
+ Supported values: `'EVM'`, `'BITCOIN'`, `'SOLANA'`, `'STELLAR'`, `'SUI'`, `'ICON'`, `'INJECTIVE'`, `'STACKS'`, `'NEAR'`.
291
+
292
+ This replaces v1's `provider instanceof EvmSpokeProvider` discrimination. Cross-bundle `instanceof` is fragile (different `@sodax/sdk` copies in dual ESM/CJS bundles can return false); the literal `chainType` field works regardless.
293
+
294
+ ---
295
+
296
+ ## 9. `ChainId` / `SpokeChainId` → `SpokeChainKey`
297
+
298
+ Type alias rename. Same value union (the chain-key strings).
299
+
300
+ ```diff
301
+ - import type { ChainId, SpokeChainId } from '@sodax/types';
302
+ + import type { SpokeChainKey } from '@sodax/sdk';
303
+ - function pickChain(id: ChainId): boolean { ... }
304
+ + function pickChain(key: SpokeChainKey): boolean { ... }
305
+ ```
306
+
307
+ Function bodies that compared `chainId === SONIC_MAINNET_CHAIN_ID` need [§1](#1-chain-identifiers)'s constant rename in addition to the type rename.
308
+
309
+ ---
310
+
311
+ ## 10. Deleted module-error types
312
+
313
+ These types were exported from v1 but are deleted in v2. Replace with `SodaxError<C>` (see [`result-and-errors.md`](result-and-errors.md) for full semantics):
314
+
315
+ - `MoneyMarketError<MoneyMarketErrorCode>`
316
+ - `IntentError<IntentErrorCode>`
317
+ - `StakingError<StakingErrorCode>`
318
+ - `BridgeError<BridgeErrorCode>`
319
+ - `MigrationError<MigrationErrorCode>`
320
+ - `AssetServiceError<AssetServiceErrorCode>`
321
+ - `ConcentratedLiquidityError<ConcentratedLiquidityErrorCode>`
322
+ - `RelayError<RelayErrorCode>`
323
+ - 5 partner error types (`PartnerFeeClaimError<...>`, etc.) and their `is<Module>Error()` type-guard helpers.
324
+
325
+ The replacement contract:
326
+
327
+ ```diff
328
+ - if (error instanceof MoneyMarketError && error.code === 'CREATE_SUPPLY_INTENT_FAILED') { … }
329
+ + if (isSodaxError(error) && error.feature === 'moneyMarket' && error.code === 'INTENT_CREATION_FAILED') { … }
330
+ ```
331
+
332
+ The full v1 → v2 code crosswalk lives in [`result-and-errors.md`](result-and-errors.md) § "v1 ↔ v2 code crosswalk".
333
+
334
+ ---
335
+
336
+ ## Cross-references
337
+
338
+ - Architectural changes (spoke-provider deletion, ConfigService, relay flow): [`architecture.md`](architecture.md).
339
+ - Result/error model details (propagation patterns, code crosswalk, return shapes): [`result-and-errors.md`](result-and-errors.md).
340
+ - v2 design context (what to use instead of each deleted symbol): [`../../integration/architecture.md`](../../integration/architecture.md).
341
+ - Lookup tables (full chain-key list, `I*WalletProvider` interfaces, public API surface): [`../../integration/reference/`](../../integration/reference/).
@@ -0,0 +1,67 @@
1
+ # v1 → v2 cross-cutting migration checklist
2
+
3
+ Work this top-down. Each step is independent enough to land as its own commit; the order minimizes typecheck noise.
4
+
5
+ ```
6
+ [ ] 1. Replace every *_MAINNET_CHAIN_ID constant with ChainKeys.* (mechanical).
7
+ See breaking-changes/type-system.md § "Chain IDs".
8
+ [ ] 2. Replace every SpokeChainId / ChainId type alias with SpokeChainKey.
9
+ Mechanical rename. Same value union.
10
+ [ ] 3. Rename XToken.xChainId → XToken.chainKey. Same for any consumer types
11
+ that mirrored that field.
12
+ [ ] 4. Remove any direct dependency on @sodax/types from package.json.
13
+ v2 @sodax/sdk barrel re-exports the entire types surface.
14
+ [ ] 5. Delete every *SpokeProvider class instantiation. Replace with passing
15
+ walletProvider (an I*WalletProvider instance) directly into SDK call
16
+ payloads.
17
+ [ ] 6. Replace every isXxxSpokeProvider(provider) guard with a chain-key
18
+ compare: chainKey === ChainKeys.<X>_MAINNET, or use
19
+ is<Family>ChainKeyType(chainKey) from @sodax/sdk.
20
+ [ ] 7. Add { raw: false } discriminator to every signed call shape that
21
+ previously took a positional spoke provider:
22
+ { intentParams, spokeProvider } → { params, raw: false, walletProvider }
23
+ [ ] 7b. Cross-cutting rename: every payload field named `spokeProvider:` (incl.
24
+ approve/allowance/utility methods that aren't signed-execution shapes)
25
+ → `walletProvider:`. Mechanical for the OBJECT-LITERAL field key; don't
26
+ blindly rename variable names of the same spelling. See
27
+ [`recipes.md`](recipes.md) § 1 "What's not safe to grep-replace".
28
+ [ ] 8. Add srcChainKey + srcAddress to every action params object that didn't
29
+ carry them in v1 (most MM, staking, dex, bridge, migration param shapes).
30
+ [ ] 9. Convert every await sodax.<service>.<method>(...) call site that previously
31
+ threw to branch on result.ok / result.error. Use isSodaxError(e) for type
32
+ narrowing.
33
+ [ ] 10. Delete imports of MoneyMarketError, IntentError, StakingError, BridgeError,
34
+ MigrationError, AssetServiceError, ConcentratedLiquidityError, RelayError,
35
+ plus the five Partner error types and their type-guard helpers.
36
+ [ ] 11. Replace any walked global lookup (hubAssets, moneyMarketSupportedTokens,
37
+ SodaTokens, supportedSpokeChains) with the equivalent sodax.config.* /
38
+ sodax.moneyMarket.getSupportedTokens*() call. Per-symbol deleted-vs-
39
+ still-exported status: see breaking-changes/architecture.md § 2.
40
+ [ ] 12. Initialize ConfigService at app startup: await sodax.config.initialize().
41
+ Falls back to packaged defaults if the backend is unreachable.
42
+ [ ] 13. Add { raw: true } to any read-only allowance check that previously took
43
+ a spoke provider but didn't actually consult it (the underlying SDK
44
+ method now requires WalletProviderSlot).
45
+ [ ] 14. For every CreateIntentResult consumer: stop destructuring as a tuple;
46
+ the v2 shape is { tx, intent, relayData }. Stop destructuring tx-pair
47
+ results as arrays — every cross-chain mutation returns
48
+ TxHashPair = { srcChainTxHash, dstChainTxHash }.
49
+ [ ] 15. For every backend-API call site: every method on IConfigApi now returns
50
+ Promise<Result<T>>. Wrap or unwrap accordingly.
51
+ [ ] 16. (Optional) Adopt isSodaxError(e) over instanceof SodaxError in cross-bundle
52
+ / cross-realm contexts.
53
+ [ ] 17. Run pnpm tsc --noEmit and start crossing items off the typecheck output.
54
+ Use each remaining error category to navigate to the relevant per-feature
55
+ migration file in features/.
56
+ ```
57
+
58
+ After items 1–17 land, the typecheck should be clean. The remaining work is per-feature behavior (cross-chain borrow / repay deltas, staking action discriminators, etc.) covered in [`features/`](features/).
59
+
60
+ ## Reading order while working the checklist
61
+
62
+ - Items 1–4: [`breaking-changes/type-system.md`](breaking-changes/type-system.md).
63
+ - Items 5–6, 11–12: [`breaking-changes/architecture.md`](breaking-changes/architecture.md).
64
+ - Items 7–8, 13: [`breaking-changes/architecture.md`](breaking-changes/architecture.md) § "WalletProviderSlot" + per-feature files.
65
+ - Items 9–10, 14, 16: [`breaking-changes/result-and-errors.md`](breaking-changes/result-and-errors.md).
66
+ - Item 15: [`features/auxiliary-services.md`](features/auxiliary-services.md) § "BackendApiService".
67
+ - Item 17 + the long tail: [`features/`](features/), one per feature you use.
@@ -0,0 +1,35 @@
1
+ # Per-feature migration playbooks — v1 → v2
2
+
3
+ One file per feature, paired with the v2 design counterpart in [`../../integration/features/`](../../integration/features/) (same filename).
4
+
5
+ | Feature | Migration file |
6
+ |---|---|
7
+ | Swap | [`swap.md`](swap.md) |
8
+ | Money Market | [`money-market.md`](money-market.md) |
9
+ | Staking | [`staking.md`](staking.md) |
10
+ | Bridge | [`bridge.md`](bridge.md) |
11
+ | DEX | [`dex.md`](dex.md) |
12
+ | ICX/bnUSD/BALN | [`icx-bnusd-baln.md`](icx-bnusd-baln.md) |
13
+ | Auxiliary services | [`auxiliary-services.md`](auxiliary-services.md) — `PartnerService` + `RecoveryService` + `BackendApiService`. The backend-API one is the load-bearing change: every method now returns `Promise<Result<T>>`. |
14
+
15
+ ## Reading order within a feature
16
+
17
+ Each per-feature file follows the same shape:
18
+
19
+ 1. **TL;DR** — the load-bearing changes in 5–10 bullets.
20
+ 2. **Type / symbol cheat sheet** — exact renames and shape diffs.
21
+ 3. **Per-method delta** — call shape v1 vs v2, return type v1 vs v2, error model v1 vs v2.
22
+ 4. **Worked example** — a representative migration of one call site, before / after.
23
+ 5. **Pitfalls** — the things that look right but compile or run wrong.
24
+ 6. **Verification** — what to run to confirm the port is complete.
25
+
26
+ ## Cross-cutting prerequisites
27
+
28
+ Before reading any feature file, finish the cross-cutting work in:
29
+
30
+ - [`../README.md`](../README.md) — top-level checklist (chain-id rename, type renames, `walletProvider` extraction).
31
+ - [`../breaking-changes/type-system.md`](../breaking-changes/type-system.md) — type imports must compile first.
32
+ - [`../breaking-changes/architecture.md`](../breaking-changes/architecture.md) — `*SpokeProvider` deletion, `ConfigService`.
33
+ - [`../breaking-changes/result-and-errors.md`](../breaking-changes/result-and-errors.md) — `Result<T>` and `SodaxError<C>`.
34
+
35
+ Per-feature work assumes those are done.
@@ -0,0 +1,156 @@
1
+ # Auxiliary services migration — v1 → v2
2
+
3
+ Pure-SDK migration playbook for `PartnerService`, `RecoveryService`, and `BackendApiService`. Three small services grouped because each has a small surface area.
4
+
5
+ Pair: [`../../integration/features/auxiliary-services.md`](../../integration/features/auxiliary-services.md).
6
+
7
+ ## TL;DR
8
+
9
+ 1. **`PartnerService`:** standard pattern. Drop `spokeProvider`; pass `walletProvider`. Add `srcChainKey` + `srcAddress` to claim params. v1's 5 typed errors collapse into `SodaxError<C>` with `feature: 'partner'`.
10
+ 2. **`RecoveryService`:** **new in v2.** No v1 equivalent — there's no migration to do for code that didn't exist before. Just integration: see [`../../integration/features/auxiliary-services.md`](../../integration/features/auxiliary-services.md).
11
+ 3. **`BackendApiService`:** the load-bearing change. **Every method now returns `Promise<Result<T>>`** (v1 returned plain `Promise<T>` and threw on failure). `IConfigApi` implementations must update method signatures.
12
+ 4. **`SubmitSwapTxRequest.srcChainId` → `srcChainKey`.** And `relayData` field is `string` (`relayData.payload`), not the `RelayExtraData` object. (Cross-cutting detail; covered in detail in [`swap.md`](swap.md).)
13
+
14
+ ## `PartnerService`
15
+
16
+ ### Type / symbol cheat sheet
17
+
18
+ | Type | v1 shape | v2 shape | Notes |
19
+ |---|---|---|---|
20
+ | Partner action params | non-generic | now generic `<K>` with `srcChainKey`, `srcAddress` | |
21
+ | Partner errors (5 types) | `PartnerFeeClaimError<...>` and 4 siblings | `SodaxError<C>` with `feature: 'partner'` | All 5 v1 typed errors collapse. |
22
+
23
+ ### v1 → v2 error code crosswalk
24
+
25
+ All 5 v1 partner error codes map to `EXECUTION_FAILED` with `error.context.action` discriminating between the operations.
26
+
27
+ ### Per-method delta
28
+
29
+ Partner operations live on `sodax.partners.feeClaim` (a `PartnerFeeClaimService`), not directly on `sodax.partners`. v1 method names also changed:
30
+
31
+ ```diff
32
+ - await sodax.partners.claimFees({ /* … */ }, spokeProvider);
33
+ + // Approve once, then configure auto-swap preference, then run swaps.
34
+ + // Full method list lives in integration/features/auxiliary-services.md.
35
+ + const approved = await sodax.partners.feeClaim.isTokenApproved({ token, srcAddress });
36
+ + if (approved.ok && !approved.value) {
37
+ + await sodax.partners.feeClaim.approveToken({
38
+ + params: { token, amount },
39
+ + raw: false,
40
+ + walletProvider,
41
+ + });
42
+ + }
43
+ ```
44
+
45
+ ### Pitfalls
46
+
47
+ 1. **Partner methods moved.** They live on `sodax.partners.feeClaim`, not `sodax.partners` directly. The parent only exposes `feeClaim` and `config` as public fields.
48
+ 2. **All 5 v1 partner errors collapse to `feature: 'partner'`.** Even though they share the `EXECUTION_FAILED` code with every other feature.
49
+
50
+ ---
51
+
52
+ ## `RecoveryService`
53
+
54
+ **No v1 equivalent.** v1 didn't have a public recovery service. Failed cross-chain operations had to be handled ad-hoc.
55
+
56
+ If you have v1 code that worked around this (e.g. manually walked the hub wallet abstraction to find stuck assets), replace it with `fetchHubAssetBalances` + `withdrawHubAsset`:
57
+
58
+ ```ts
59
+ const balances = await sodax.recovery.fetchHubAssetBalances({ /* user / hub-wallet args */ });
60
+ if (balances.ok && balances.value.length > 0) {
61
+ await sodax.recovery.withdrawHubAsset({
62
+ params: { /* hub-asset address, amount, destination spoke chain + address */ },
63
+ raw: false,
64
+ walletProvider: sonicWp,
65
+ });
66
+ }
67
+ ```
68
+
69
+ See [`../../integration/features/auxiliary-services.md`](../../integration/features/auxiliary-services.md) § "RecoveryService".
70
+
71
+ ---
72
+
73
+ ## `BackendApiService`
74
+
75
+ The load-bearing v1 → v2 change here is **`Result`-wrapping every method**.
76
+
77
+ ### Type / symbol cheat sheet
78
+
79
+ | Method | v1 return | v2 return |
80
+ |---|---|---|
81
+ | `submitSwapTx` | `Promise<SubmitSwapTxResponse>` | `Promise<Result<SubmitSwapTxResponse>>` |
82
+ | `getIntentByHash` | `Promise<IntentResponse>` | `Promise<Result<IntentResponse>>` |
83
+ | `getIntentByTxHash` | (n/a in v1) | `Promise<Result<IntentResponse>>` (v2-new) |
84
+ | `getOrderbook` (was `getSolverOrderbook`) | `Promise<OrderbookEntry[]>` | `Promise<Result<OrderbookEntry[]>>` |
85
+ | `getUserIntents` (was `getUserSwapHistory`) | `Promise<IntentResponse[]>` | `Promise<Result<IntentResponse[]>>` |
86
+ | `getChains` | `Promise<ChainConfig[]>` | `Promise<Result<GetChainsApiResponse>>` |
87
+ | `getSwapTokens` | `Promise<SwapTokenConfig>` | `Promise<Result<GetSwapTokensApiResponse>>` |
88
+ | `getSwapTokensByChainId` | `Promise<XToken[]>` | `Promise<Result<XToken[]>>` |
89
+ | `getMoneyMarketTokens` | `Promise<MMTokenConfig>` | `Promise<Result<GetMoneyMarketTokensApiResponse>>` |
90
+ | `getMoneyMarketTokensByChainId` | `Promise<XToken[]>` | `Promise<Result<XToken[]>>` |
91
+ | `SubmitSwapTxRequest.srcChainId` | numeric chain id | renamed → `srcChainKey: SpokeChainKey` |
92
+ | `SubmitSwapTxRequest.relayData` | `RelayExtraData` object | now `string` (use `relayData.payload`) |
93
+
94
+ ### Per-method delta
95
+
96
+ ```diff
97
+ - const response: SubmitSwapTxResponse = await sodax.backendApi.submitSwapTx(request);
98
+ - // throws on failure
99
+ + const result = await sodax.backendApi.submitSwapTx({
100
+ + txHash: spokeTxHash as string,
101
+ + srcChainKey: src.chain, // was: srcChainId
102
+ + walletAddress: '0x…',
103
+ + intent: swapIntentData,
104
+ + relayData: relayData.payload, // was: relayData (object)
105
+ + });
106
+ + if (!result.ok) {
107
+ + // result.error: SodaxError with feature: 'swap', context.api: 'backend'
108
+ + return;
109
+ + }
110
+ + const response = result.value;
111
+ ```
112
+
113
+ ### Custom `IConfigApi` (sandbox / test fixtures)
114
+
115
+ If you implemented `IConfigApi` for a sandbox or test fixture:
116
+
117
+ ```diff
118
+ const sandboxApi: IConfigApi = {
119
+ - async getChains(): Promise<ChainConfig[]> {
120
+ - return [/* fixture */];
121
+ - },
122
+ - async getSwapTokens(): Promise<SwapTokenConfig> { /* … */ },
123
+ + async getChains(): Promise<Result<ChainConfig[], unknown>> {
124
+ + return { ok: true, value: [/* fixture */] };
125
+ + },
126
+ + async getSwapTokens(): Promise<Result<SwapTokenConfig, unknown>> { /* … */ },
127
+ // …5 methods total
128
+ };
129
+ ```
130
+
131
+ Every method on the contract returns `Promise<Result<T>>` in v2.
132
+
133
+ ### Pitfalls
134
+
135
+ 1. **`SubmitSwapTxRequest.relayData` is `string`, not the `RelayExtraData` object.** v1 took the object; v2 takes the `payload` field as a string.
136
+ 2. **Backend errors carry `error.context.api === 'backend'`** but the `feature` reflects the call site (`'swap'` for `submitSwapTx`, `'moneyMarket'` for MM-related backend calls, etc.). Use both for logger tag pairs.
137
+ 3. **Custom `IConfigApi` implementations must return `Result<T>`** — old throw-on-error implementations will compile-error against the v2 interface.
138
+
139
+ ---
140
+
141
+ ## Verification
142
+
143
+ ```bash
144
+ pnpm -C <your-app-dir> checkTs
145
+
146
+ # Targeted scans:
147
+ grep -rE "spokeProvider:\s*\w+|isPartnerError\b|PartnerFeeClaimError\b" src/
148
+ grep -rE "srcChainId:\s*\w+|\.relayData(?!\s*\.payload)" src/ # legacy field name + non-string relayData
149
+ ```
150
+
151
+ ## Cross-references
152
+
153
+ - v2 auxiliary services usage: [`../../integration/features/auxiliary-services.md`](../../integration/features/auxiliary-services.md).
154
+ - `submitSwapTx` flow with `createIntent` upstream: [`./swap.md`](swap.md) (the swap migration covers the request-shape changes in detail).
155
+ - Result/error model: [`../breaking-changes/result-and-errors.md`](../breaking-changes/result-and-errors.md).
156
+ - `IConfigApi` Result-wrapping cross-cutting note: [`../breaking-changes/type-system.md`](../breaking-changes/type-system.md) § 6.