@sodax/sdk 1.5.7-beta → 2.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -7
- package/ai-exported/AGENTS.md +99 -0
- package/ai-exported/integration/README.md +41 -0
- package/ai-exported/integration/ai-rules.md +75 -0
- package/ai-exported/integration/architecture.md +519 -0
- package/ai-exported/integration/chain-specifics.md +189 -0
- package/ai-exported/integration/features/README.md +19 -0
- package/ai-exported/integration/features/auxiliary-services.md +189 -0
- package/ai-exported/integration/features/bridge.md +136 -0
- package/ai-exported/integration/features/dex.md +182 -0
- package/ai-exported/integration/features/icx-bnusd-baln.md +181 -0
- package/ai-exported/integration/features/money-market.md +198 -0
- package/ai-exported/integration/features/staking.md +166 -0
- package/ai-exported/integration/features/swap.md +207 -0
- package/ai-exported/integration/quickstart.md +213 -0
- package/ai-exported/integration/recipes/README.md +21 -0
- package/ai-exported/integration/recipes/backend-server-init.md +69 -0
- package/ai-exported/integration/recipes/chain-key-narrowing.md +65 -0
- package/ai-exported/integration/recipes/gas-estimation.md +33 -0
- package/ai-exported/integration/recipes/initialize-sodax.md +53 -0
- package/ai-exported/integration/recipes/raw-tx-flow.md +71 -0
- package/ai-exported/integration/recipes/result-and-errors.md +104 -0
- package/ai-exported/integration/recipes/signed-tx-flow.md +46 -0
- package/ai-exported/integration/recipes/testing.md +101 -0
- package/ai-exported/integration/reference/README.md +18 -0
- package/ai-exported/integration/reference/chain-keys.md +67 -0
- package/ai-exported/integration/reference/error-codes.md +165 -0
- package/ai-exported/integration/reference/glossary.md +32 -0
- package/ai-exported/integration/reference/public-api.md +138 -0
- package/ai-exported/integration/reference/wallet-providers.md +62 -0
- package/ai-exported/migration/README.md +58 -0
- package/ai-exported/migration/ai-rules.md +80 -0
- package/ai-exported/migration/breaking-changes/architecture.md +342 -0
- package/ai-exported/migration/breaking-changes/result-and-errors.md +363 -0
- package/ai-exported/migration/breaking-changes/type-system.md +321 -0
- package/ai-exported/migration/checklist.md +61 -0
- package/ai-exported/migration/features/README.md +35 -0
- package/ai-exported/migration/features/auxiliary-services.md +156 -0
- package/ai-exported/migration/features/bridge.md +125 -0
- package/ai-exported/migration/features/dex.md +143 -0
- package/ai-exported/migration/features/icx-bnusd-baln.md +151 -0
- package/ai-exported/migration/features/money-market.md +214 -0
- package/ai-exported/migration/features/staking.md +138 -0
- package/ai-exported/migration/features/swap.md +198 -0
- package/ai-exported/migration/recipes.md +288 -0
- package/ai-exported/migration/reference/README.md +18 -0
- package/ai-exported/migration/reference/deleted-exports.md +126 -0
- package/ai-exported/migration/reference/error-code-crosswalk.md +104 -0
- package/ai-exported/migration/reference/return-shapes.md +49 -0
- package/ai-exported/migration/reference/sodax-config.md +52 -0
- package/dist/index.cjs +32076 -31544
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8604 -7136
- package/dist/index.d.ts +8604 -7136
- package/dist/index.mjs +31893 -31402
- package/dist/index.mjs.map +1 -1
- package/package.json +20 -12
|
@@ -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).
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# Migration recipes — v1 → v2
|
|
2
|
+
|
|
3
|
+
Practical patterns for porting consumer code without rewriting everything in one pass. Three recipes:
|
|
4
|
+
|
|
5
|
+
1. [Codemod patterns](#1-codemod-patterns) — regex find/replace + a small `ts-morph` script for the renames that grep can't safely handle.
|
|
6
|
+
2. [Error-shape adapter](#2-error-shape-adapter) — adapt v2 `SodaxError` onto v1 `{ code, data }` branches so existing error-formatting helpers keep working.
|
|
7
|
+
3. [Result adapter](#3-result-adapter) — wrap v2 `Result<T>` in a v1-style throw shim for incremental conversion of call sites.
|
|
8
|
+
|
|
9
|
+
These are migration-only — once the port is complete, delete them. They're not patterns for new code.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. Codemod patterns
|
|
14
|
+
|
|
15
|
+
### What's safe to grep-replace
|
|
16
|
+
|
|
17
|
+
| Change | Find | Replace | Notes |
|
|
18
|
+
|---|---|---|---|
|
|
19
|
+
| Chain-id constants | `(\w+)_MAINNET_CHAIN_ID` | `ChainKeys.$1_MAINNET` | Mechanical. After: fix `import` statements. |
|
|
20
|
+
| `xChainId` field on `XToken` | `\.xChainId\b` | `.chainKey` | Token field rename. Audit first — some non-token types may use `xChainId` differently. |
|
|
21
|
+
| `Token` type rename | `\bimport(.*)\bToken\b(.*)\bfrom 'sodax/types'` | `import$1XToken$2from '@sodax/sdk'` | Best done with `ts-morph` to avoid touching unrelated `Token` identifiers. |
|
|
22
|
+
| `SpokeChainId` → `SpokeChainKey` | `\b(SpokeChainId\|ChainId)\b` (in type positions) | `SpokeChainKey` | Audit — `ChainId` is also used by 3rd-party libs (viem, etc.). Limit to `@sodax/types` imports. |
|
|
23
|
+
| `AddressType` → `BtcAddressType` | `\bAddressType\b` (in `@sodax/types` import positions) | `BtcAddressType` | |
|
|
24
|
+
|
|
25
|
+
### What's not safe to grep-replace
|
|
26
|
+
|
|
27
|
+
- `srcChain` → `srcChainKey` on **request** types only. Read shapes (`Intent.srcChain`, `IntentResponse.srcChain`) keep `srcChain` as the relay chain id. Use a `ts-morph` script keyed by parameter type.
|
|
28
|
+
- `spokeProvider` → `walletProvider`. The replacement isn't 1-to-1 (`spokeProvider` was a class instance; `walletProvider` is a separate field). You're better off doing this manually per call site.
|
|
29
|
+
- `instanceof EvmSpokeProvider` → chain-key check. Chain-specific replacement varies (some need `chainKey === ChainKeys.X`, some `getChainType(chainKey) === 'EVM'`).
|
|
30
|
+
|
|
31
|
+
### `ts-morph` script for chain-id imports
|
|
32
|
+
|
|
33
|
+
When you have many files, a one-shot script for the chain-id rename. Run from the root of your consumer repo with `tsx codemod-chain-ids.ts`:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
// codemod-chain-ids.ts
|
|
37
|
+
import { Project, SyntaxKind } from 'ts-morph';
|
|
38
|
+
|
|
39
|
+
const project = new Project({ tsConfigFilePath: 'tsconfig.json' });
|
|
40
|
+
const sodaxImports = ['@sodax/types', '@sodax/sdk'];
|
|
41
|
+
const renamed = new Set<string>();
|
|
42
|
+
|
|
43
|
+
for (const file of project.getSourceFiles('src/**/*.{ts,tsx}')) {
|
|
44
|
+
let edited = false;
|
|
45
|
+
|
|
46
|
+
for (const decl of file.getImportDeclarations()) {
|
|
47
|
+
if (!sodaxImports.includes(decl.getModuleSpecifierValue())) continue;
|
|
48
|
+
|
|
49
|
+
const named = decl.getNamedImports();
|
|
50
|
+
const toRemove: typeof named = [];
|
|
51
|
+
let needsChainKeysImport = false;
|
|
52
|
+
|
|
53
|
+
for (const imp of named) {
|
|
54
|
+
const name = imp.getName();
|
|
55
|
+
const m = name.match(/^(.+)_MAINNET_CHAIN_ID$/);
|
|
56
|
+
if (!m) continue;
|
|
57
|
+
const newName = `ChainKeys.${m[1]}_MAINNET`;
|
|
58
|
+
// Replace usages inside the file
|
|
59
|
+
file.forEachDescendant(node => {
|
|
60
|
+
if (node.isKind(SyntaxKind.Identifier) && node.getText() === name) {
|
|
61
|
+
node.replaceWithText(newName);
|
|
62
|
+
edited = true;
|
|
63
|
+
renamed.add(name);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
toRemove.push(imp);
|
|
67
|
+
needsChainKeysImport = true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
for (const imp of toRemove) imp.remove();
|
|
71
|
+
if (needsChainKeysImport) {
|
|
72
|
+
const existing = decl.getNamedImports().find(i => i.getName() === 'ChainKeys');
|
|
73
|
+
if (!existing) decl.addNamedImport('ChainKeys');
|
|
74
|
+
}
|
|
75
|
+
if (decl.getNamedImports().length === 0 && !decl.getNamespaceImport() && !decl.getDefaultImport()) {
|
|
76
|
+
decl.remove();
|
|
77
|
+
edited = true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (edited) await file.save();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
console.log('Renamed constants:', [...renamed].join(', '));
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Exit codes and post-run checks:
|
|
88
|
+
|
|
89
|
+
- **Run `tsc --noEmit` after** — confirm imports resolve. The script doesn't touch `ChainKey` type imports (which you may also need to add manually in some files).
|
|
90
|
+
- **Re-run with `--dry-run`** semantics by commenting out `file.save()` to preview the diff.
|
|
91
|
+
|
|
92
|
+
### Pitfall
|
|
93
|
+
|
|
94
|
+
The `ts-morph` script above edits in-place. Commit your tree before running.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 2. Error-shape adapter
|
|
99
|
+
|
|
100
|
+
If your consumer code has `getMmErrorText`, `getSwapErrorText`, or similar helpers that branch on a v1 error object's `.code` and `.data.error`, the minimal-change migration is to wrap incoming v2 `SodaxError` instances at the entry point of each helper:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
// shared/error-shape-adapter.ts
|
|
104
|
+
import { isSodaxError } from '@sodax/sdk';
|
|
105
|
+
|
|
106
|
+
export type V1ErrorShape = {
|
|
107
|
+
code?: string;
|
|
108
|
+
message?: string;
|
|
109
|
+
data?: { error?: unknown };
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Adapt v2 SodaxError onto the v1 `{ code, message, data: { error } }` shape so
|
|
114
|
+
* existing v1-style error helpers keep working without rewriting every branch.
|
|
115
|
+
*
|
|
116
|
+
* Migration only — replace with `(error.feature, error.code)` branching once the
|
|
117
|
+
* helper is rewritten.
|
|
118
|
+
*/
|
|
119
|
+
export function adaptToV1ErrorShape(error: unknown): V1ErrorShape | null {
|
|
120
|
+
if (error == null) return null;
|
|
121
|
+
|
|
122
|
+
// v2 SodaxError → v1-shaped object with code on top level.
|
|
123
|
+
if (isSodaxError(error)) {
|
|
124
|
+
return {
|
|
125
|
+
code: error.code,
|
|
126
|
+
message: error.message,
|
|
127
|
+
data: { error: error.cause },
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Plain Error (no code) — fall back to message.
|
|
132
|
+
if (error instanceof Error) {
|
|
133
|
+
return { code: error.message, message: error.message };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Already v1 shape — pass through.
|
|
137
|
+
if (typeof error === 'object') {
|
|
138
|
+
return error as V1ErrorShape;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Usage
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
// Before:
|
|
149
|
+
function getMmErrorText(error: unknown): string {
|
|
150
|
+
if (error instanceof MoneyMarketError) {
|
|
151
|
+
if (error.code === 'CREATE_SUPPLY_INTENT_FAILED') return 'Could not build supply';
|
|
152
|
+
if (error.code === 'SUPPLY_FAILED') return 'Supply failed';
|
|
153
|
+
}
|
|
154
|
+
return 'Unknown error';
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// After (adapter at the top, branches keep working):
|
|
158
|
+
function getMmErrorText(error: unknown): string {
|
|
159
|
+
const sdkError = adaptToV1ErrorShape(error);
|
|
160
|
+
if (sdkError?.code === 'INTENT_CREATION_FAILED') return 'Could not build supply'; // v2 code
|
|
161
|
+
if (sdkError?.code === 'EXECUTION_FAILED') return 'Supply failed'; // v2 code
|
|
162
|
+
return 'Unknown error';
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Final-form (recommended)
|
|
167
|
+
|
|
168
|
+
After the adapter is in place, gradually rewrite each helper to use `(feature, code)` directly. The adapter is a stepping stone, not the destination:
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
import { isSodaxError } from '@sodax/sdk';
|
|
172
|
+
|
|
173
|
+
function getMmErrorText(error: unknown): string {
|
|
174
|
+
if (!isSodaxError(error) || error.feature !== 'moneyMarket') return 'Unknown error';
|
|
175
|
+
switch (error.code) {
|
|
176
|
+
case 'INTENT_CREATION_FAILED':
|
|
177
|
+
return error.context?.action === 'supply' ? 'Could not build supply' : 'Could not build operation';
|
|
178
|
+
case 'EXECUTION_FAILED':
|
|
179
|
+
return `${error.context?.action ?? 'operation'} failed`;
|
|
180
|
+
case 'RELAY_TIMEOUT':
|
|
181
|
+
return 'Cross-chain relay timed out';
|
|
182
|
+
case 'TX_VERIFICATION_FAILED':
|
|
183
|
+
return 'Transaction could not be verified on the source chain';
|
|
184
|
+
default:
|
|
185
|
+
return 'Unexpected error';
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
See [`reference/error-code-crosswalk.md`](reference/error-code-crosswalk.md) for the full v1 → v2 code crosswalk and [`breaking-changes/result-and-errors.md`](breaking-changes/result-and-errors.md) § 6 for the discrimination patterns this snippet uses.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## 3. Result adapter
|
|
195
|
+
|
|
196
|
+
If converting every call site to branch on `result.ok` in one pass isn't realistic, use a `throwIfError` shim during migration. Then convert call sites at your own pace.
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
// shared/result-adapter.ts
|
|
200
|
+
import { isSodaxError } from '@sodax/sdk';
|
|
201
|
+
import type { Result } from '@sodax/sdk';
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Throw on { ok: false }. v1-shape callers can `await throwIfError(result)` and
|
|
205
|
+
* keep their existing try/catch blocks during migration.
|
|
206
|
+
*
|
|
207
|
+
* The thrown value is the original error from the Result — typically a SodaxError.
|
|
208
|
+
* Existing instanceof / .code branches will still work via adaptToV1ErrorShape.
|
|
209
|
+
*
|
|
210
|
+
* Migration only — once the call site is converted to branch on result.ok directly,
|
|
211
|
+
* remove the throwIfError wrap.
|
|
212
|
+
*/
|
|
213
|
+
export function throwIfError<T>(result: Result<T, unknown>): T {
|
|
214
|
+
if (!result.ok) {
|
|
215
|
+
if (isSodaxError(result.error)) throw result.error;
|
|
216
|
+
if (result.error instanceof Error) throw result.error;
|
|
217
|
+
throw new Error(`unwrap failed: ${String(result.error)}`);
|
|
218
|
+
}
|
|
219
|
+
return result.value;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Same as throwIfError, but coerces non-Error errors to a thrown Error
|
|
224
|
+
* (useful when downstream code only catches Error).
|
|
225
|
+
*/
|
|
226
|
+
export function throwAsError<T>(result: Result<T, unknown>, fallbackMessage = 'operation failed'): T {
|
|
227
|
+
if (!result.ok) {
|
|
228
|
+
const e = result.error;
|
|
229
|
+
if (e instanceof Error) throw e;
|
|
230
|
+
throw new Error(typeof e === 'string' ? e : fallbackMessage);
|
|
231
|
+
}
|
|
232
|
+
return result.value;
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Usage during migration
|
|
237
|
+
|
|
238
|
+
```ts
|
|
239
|
+
// Before (v1):
|
|
240
|
+
try {
|
|
241
|
+
const txHash = await sodax.moneyMarket.supply({ params, spokeProvider });
|
|
242
|
+
/* … */
|
|
243
|
+
} catch (e) {
|
|
244
|
+
if (e instanceof MoneyMarketError && e.code === 'SUPPLY_FAILED') /* … */
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// During migration (with shim):
|
|
248
|
+
try {
|
|
249
|
+
const { srcChainTxHash } = await throwIfError(
|
|
250
|
+
await sodax.moneyMarket.supply({ params, raw: false, walletProvider }),
|
|
251
|
+
);
|
|
252
|
+
/* … */
|
|
253
|
+
} catch (e) {
|
|
254
|
+
// existing v1-shape branches keep working via adaptToV1ErrorShape;
|
|
255
|
+
// SodaxError instances satisfy the same checks once you migrate them
|
|
256
|
+
if (e instanceof Error && /* … */) /* … */
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Final-form (recommended)
|
|
261
|
+
|
|
262
|
+
Once the call site is converted, drop `throwIfError`:
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
const result = await sodax.moneyMarket.supply({ params, raw: false, walletProvider });
|
|
266
|
+
if (!result.ok) {
|
|
267
|
+
setError(getMmErrorText(result.error));
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
const { srcChainTxHash } = result.value;
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Pitfall — the v1-style `try { await sodax.<method>(...) } catch` does not work
|
|
274
|
+
|
|
275
|
+
A common mistake during migration: keeping the `try/catch` block but updating the inner call to v2 shape, expecting it to still throw. **It won't.** v2 `Result<T>` resolves on failure — the `catch` only fires for synchronous wrapper exceptions (e.g. missing `walletProvider`). Either:
|
|
276
|
+
|
|
277
|
+
- Wrap the call in `throwIfError` (this recipe), so failures throw.
|
|
278
|
+
- Branch on `result.ok` (preferred end state).
|
|
279
|
+
|
|
280
|
+
Don't leave the `try/catch` in place expecting it to catch SDK-level failures — it can't.
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## Cross-references
|
|
285
|
+
|
|
286
|
+
- The breaking changes that motivate these recipes: [`breaking-changes/type-system.md`](breaking-changes/type-system.md), [`breaking-changes/architecture.md`](breaking-changes/architecture.md), [`breaking-changes/result-and-errors.md`](breaking-changes/result-and-errors.md).
|
|
287
|
+
- Per-feature playbooks (which assume these recipes are in your toolkit): [`features/`](features/).
|
|
288
|
+
- v2 design context (the patterns you're migrating *to*): [`../integration/recipes/`](../integration/recipes/).
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Migration reference — `@sodax/sdk` v1 → v2
|
|
2
|
+
|
|
3
|
+
Tables. Each file is a focused lookup; the prose explanations live in `../breaking-changes/` and `../features/`.
|
|
4
|
+
|
|
5
|
+
| File | Contents |
|
|
6
|
+
|---|---|
|
|
7
|
+
| [`deleted-exports.md`](deleted-exports.md) | Comprehensive table of every removed v1 export with its v2 replacement: spoke-provider classes & guards, static lookup tables, type aliases, constants, error types, per-feature param-shape changes. |
|
|
8
|
+
| [`sodax-config.md`](sodax-config.md) | `SodaxConfig` constructor reshape: `swaps` vs `solver` field split, `rpcConfig` keying change, `hubProviderConfig` → `hubConfig` rename, `configService` injection point gone. |
|
|
9
|
+
| [`error-code-crosswalk.md`](error-code-crosswalk.md) | Per-feature v1 module-error code → v2 `(feature, code, context)` tuple. Money market, swap, staking, bridge, migration, DEX, relay, partner, recovery. |
|
|
10
|
+
| [`return-shapes.md`](return-shapes.md) | Per-method return-shape diffs. `CreateIntentResult` tuple→object, every cross-chain mutation now returns `TxHashPair`, `getBridgeableAmount` returns `BridgeLimit`, `getStakeRatio` returns a tuple, etc. |
|
|
11
|
+
|
|
12
|
+
## Cross-references
|
|
13
|
+
|
|
14
|
+
- [`../README.md`](../README.md) — migration overview.
|
|
15
|
+
- [`../checklist.md`](../checklist.md) — top-level migration checklist.
|
|
16
|
+
- [`../ai-rules.md`](../ai-rules.md) — DO / DO NOT / workflow.
|
|
17
|
+
- [`../breaking-changes/`](../breaking-changes/) — the prose that explains what these tables tabulate.
|
|
18
|
+
- v2 design context: [`../../integration/architecture.md`](../../integration/architecture.md) and [`../../integration/reference/`](../../integration/reference/).
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Deleted / replaced exports inventory
|
|
2
|
+
|
|
3
|
+
Every v1 export that's gone or repurposed in v2 — and its v2 successor. If you see `error TS2305: Module '"@sodax/sdk"' has no exported member '<X>'`, find `<X>` in the left column.
|
|
4
|
+
|
|
5
|
+
Two categories worth distinguishing:
|
|
6
|
+
- **Truly deleted** — the v1 symbol is gone; an import will fail compile (`TS2305`).
|
|
7
|
+
- **Name preserved, shape replaced** — a v1 `import` still compiles, but the runtime shape changed. Silent breakage if you read v1-only fields.
|
|
8
|
+
|
|
9
|
+
> Scope note: This doc only lists symbols that **don't import anymore** or **silently changed shape**. For v1 static constants that are still exported in v2 but should yield to the dynamic service API, see [`../breaking-changes/architecture.md`](../breaking-changes/architecture.md) § 2.
|
|
10
|
+
|
|
11
|
+
### Spoke-provider classes + guards
|
|
12
|
+
|
|
13
|
+
| v1 export | v2 replacement |
|
|
14
|
+
|---|---|
|
|
15
|
+
| `EvmSpokeProvider` (class) | None — pass `walletProvider` + `srcChainKey` to SDK calls. See [`../breaking-changes/architecture.md`](../breaking-changes/architecture.md) § 1. |
|
|
16
|
+
| `SonicSpokeProvider` (class) | Same. |
|
|
17
|
+
| `SolanaSpokeProvider` (class) | Same. |
|
|
18
|
+
| `SuiSpokeProvider` (class) | Same. |
|
|
19
|
+
| `IconSpokeProvider` (class) | Same. |
|
|
20
|
+
| `InjectiveSpokeProvider` (class) | Same. |
|
|
21
|
+
| `StellarSpokeProvider` / `StellarBaseSpokeProvider` (classes) | Same. |
|
|
22
|
+
| `StacksSpokeProvider` (class) | Same. |
|
|
23
|
+
| `BitcoinSpokeProvider` (class) | Same. |
|
|
24
|
+
| `NearSpokeProvider` (class) | Same. |
|
|
25
|
+
| `SpokeProvider` (union type) | None — broad-union typing replaced by `srcChainKey: SpokeChainKey` + `walletProvider: GetWalletProviderType<K>`. |
|
|
26
|
+
| `isEvmSpokeProvider`, `isSolanaSpokeProvider`, `isBitcoinSpokeProvider`, `isStellarSpokeProvider`, `isIconSpokeProvider`, `isSuiSpokeProvider`, `isInjectiveSpokeProvider`, `isStacksSpokeProvider`, `isNearSpokeProvider`, `isSonicSpokeProvider` | `getChainType(chainKey) === '<FAMILY>'`, or family-level `is<Family>ChainKeyType(chainKey)` from `@sodax/sdk`. See [`../breaking-changes/architecture.md`](../breaking-changes/architecture.md) § 1. |
|
|
27
|
+
|
|
28
|
+
### Static lookup tables and helpers
|
|
29
|
+
|
|
30
|
+
| v1 export | v2 replacement |
|
|
31
|
+
|---|---|
|
|
32
|
+
| `hubAssets` | `XToken.vault` / `XToken.hubAsset` baked in; or `sodax.config.getOriginalAssetAddress(...)`. See [`../breaking-changes/architecture.md`](../breaking-changes/architecture.md) § 2. |
|
|
33
|
+
| `getHubChainConfig()` (free function) | `sodax.config.getHubChainConfig()` (now a method on `ConfigService`, accessed via the `Sodax` instance). |
|
|
34
|
+
| `EvmWalletAbstraction` (class) | `sodax.hubProvider.getUserHubWalletAddress(...)` (the equivalent functionality lives on `EvmHubProvider`, accessed via the `Sodax` instance). |
|
|
35
|
+
|
|
36
|
+
### Type aliases
|
|
37
|
+
|
|
38
|
+
| v1 export | v2 replacement |
|
|
39
|
+
|---|---|
|
|
40
|
+
| `ChainId` (type) | `SpokeChainKey` (or `ChainKey` for the broader union including the hub). |
|
|
41
|
+
| `SpokeChainId` (type) | `SpokeChainKey`. |
|
|
42
|
+
| `EvmChainId` (type) | `EvmChainKey` (subset of `SpokeChainKey`). |
|
|
43
|
+
| `HubChainId` (type) | `HubChainKey` (literal `'sonic'`). |
|
|
44
|
+
| `Token` (type) | `XToken`. See [`../breaking-changes/type-system.md`](../breaking-changes/type-system.md) § 4. |
|
|
45
|
+
| `AddressType` (type — `'P2PKH' \| 'P2SH' \| 'P2WPKH' \| 'P2TR'`) | `BtcAddressType` (renamed; same shape). See [`../breaking-changes/type-system.md`](../breaking-changes/type-system.md) § 7. |
|
|
46
|
+
|
|
47
|
+
> Note: `BtcWalletAddressType` (`'taproot' | 'segwit'`, wallet-UI choice) is preserved in v2 with the same shape — it is **not** the same thing as `BtcAddressType` (on-chain address format). They coexist; do not blindly rename one to the other.
|
|
48
|
+
|
|
49
|
+
### Constants
|
|
50
|
+
|
|
51
|
+
| v1 export | v2 replacement |
|
|
52
|
+
|---|---|
|
|
53
|
+
| `*_MAINNET_CHAIN_ID` (20 constants) | `ChainKeys.*` (single namespace). See [`../breaking-changes/type-system.md`](../breaking-changes/type-system.md) § 1 for the full table. |
|
|
54
|
+
|
|
55
|
+
### Wallet shims
|
|
56
|
+
|
|
57
|
+
| v1 export | v2 replacement |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `CustomProvider` (Hana-wallet window typedecl) | None. Window declaration becomes `unknown` or imports directly from the wallet vendor. Low-level Hana-extension helper functions (`requestAddress`, `requestSigning`, `requestJsonRpc`) ship from `@sodax/sdk` for consumers building their own Hana-based `IIconWalletProvider`. |
|
|
60
|
+
|
|
61
|
+
### Error types and guards
|
|
62
|
+
|
|
63
|
+
#### Error types — name preserved, shape replaced
|
|
64
|
+
|
|
65
|
+
The following v1 error types were **plain object literals** `{ code: T; data: GetXxxError<T> }`. v2 keeps the same export names but redefines them as type aliases for the canonical `SodaxError<NarrowCode>` class instance. **A v1 `import { MoneyMarketError } from '@sodax/sdk'` still compiles** — but reading `err.data` will silently fail at runtime because the v2 shape is `{ name, code, feature, message, stack, context, cause }`. Treat these as "shape replaced" rather than deleted.
|
|
66
|
+
|
|
67
|
+
| v1 shape | v2 shape | What to read |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| `MoneyMarketError<MoneyMarketErrorCode> = { code, data }` | `MoneyMarketError = SodaxError<MoneyMarketErrorCode>` (class instance) | `err.code`, `err.feature === 'moneyMarket'`, `err.context`, `err.cause`. See [`error-code-crosswalk.md`](error-code-crosswalk.md) for code crosswalk. |
|
|
70
|
+
| `BridgeError<BridgeErrorCode> = { code, data }` | `BridgeError = SodaxError<BridgeErrorCode>` | Same pattern; `err.feature === 'bridge'`. |
|
|
71
|
+
| `StakingError<StakingErrorCode> = { code, data }` | `StakingError = SodaxError<StakingErrorCode>` | Same pattern; `err.feature === 'staking'`. |
|
|
72
|
+
| `MigrationError<MigrationErrorCode> = { code, data }` | `MigrationError = SodaxError<MigrationErrorCode>` | Same pattern; `err.feature === 'migration'`. |
|
|
73
|
+
|
|
74
|
+
#### Error types — fully deleted
|
|
75
|
+
|
|
76
|
+
| v1 export | v2 replacement |
|
|
77
|
+
|---|---|
|
|
78
|
+
| `IntentError<IntentErrorCode>`, plus `IntentErrorCode`, `IntentErrorData` | `SwapError = SodaxError<SwapErrorCode>` (renamed). `feature: 'swap'`. |
|
|
79
|
+
| `AssetServiceError<AssetServiceErrorCode>`, plus the union | `DexError = SodaxError<DexErrorCode>`. `feature: 'dex'`. |
|
|
80
|
+
| `ConcentratedLiquidityError<ConcentratedLiquidityErrorCode>`, plus the union | `DexError = SodaxError<DexErrorCode>` (asset + CL collapsed into one feature). |
|
|
81
|
+
| `RelayError<RelayErrorCode>`, plus the union | `SodaxError<C>` with the lower-level relay code on `error.context.relayCode`. |
|
|
82
|
+
| `SetSwapPreferenceError`, `CreateIntentAutoSwapError`, `WaitIntentAutoSwapError`, `UnknownIntentAutoSwapError`, `ExecuteIntentAutoSwapError` (5 distinct partner error types in `PartnerFeeClaimService.ts`) | `PartnerError = SodaxError<PartnerErrorCode>`. `feature: 'partner'`. |
|
|
83
|
+
|
|
84
|
+
#### Type guards — deleted
|
|
85
|
+
|
|
86
|
+
v1 only exposed **specific per-failure-mode guards**. v2 deleted all of these and instead ships **feature-level guards** + helper builders (`isFeatureError('<feature>')`, `isCodeMember(codeSet)`).
|
|
87
|
+
|
|
88
|
+
| v1 deleted guard | v2 replacement |
|
|
89
|
+
|---|---|
|
|
90
|
+
| `isIntentCreationFailedError(e)` | `isSwapCreateIntentError(e)` or `isSodaxError(e) && e.code === 'INTENT_CREATION_FAILED' && e.feature === 'swap'`. |
|
|
91
|
+
| `isIntentSubmitTxFailedError(e)` | `isSodaxError(e) && e.code === 'TX_SUBMIT_FAILED'`. |
|
|
92
|
+
| `isIntentPostExecutionFailedError(e)` | `isSodaxError(e) && e.feature === 'swap' && e.code === 'EXECUTION_FAILED' && e.context?.phase === 'postExecution'`. |
|
|
93
|
+
| `isWaitUntilIntentExecutedFailed(e)` | `isSodaxError(e) && e.feature === 'swap' && e.code === 'RELAY_TIMEOUT'`. The v1 guard fired when the destination packet never reached `executed`; in v2 that surfaces as the unified `RELAY_TIMEOUT` code (with the underlying relay code on `error.context.relayCode`). |
|
|
94
|
+
| `isIntentCreationUnknownError(e)` | `isSodaxError(e) && e.code === 'UNKNOWN' && e.feature === 'swap'`. |
|
|
95
|
+
| `isMoneyMarketSubmitTxFailedError`, `isMoneyMarketRelayTimeoutError`, `isMoneyMarketCreate{Supply,Borrow,Withdraw,Repay}IntentFailedError`, `isMoneyMarket{Supply,Borrow,Withdraw,Repay}UnknownError` (10 specific guards) | `isMoneyMarketError(e)` (new in v2) for the feature-level check, then narrow on `e.code` / `e.context.action`. |
|
|
96
|
+
| `isCreateIntentAutoSwapError`, `isWaitIntentAutoSwapError`, `isUnknownIntentAutoSwapError`, `isSetSwapPreferenceError` (4 partner guards) | `isPartnerError(e)` (new in v2) for the feature-level check, then narrow on `e.code` / `e.context.action`. |
|
|
97
|
+
|
|
98
|
+
> Note: `isMoneyMarketError`, `isBridgeError`, `isStakingError`, `isMigrationError`, `isSwapError`, `isDexError`, `isPartnerError`, `isRecoveryError` did **not** exist in v1 — v2 added them as new feature-level guards alongside `isSodaxError` and the `isFeatureError('<feature>')` factory. See [`../breaking-changes/result-and-errors.md`](../breaking-changes/result-and-errors.md) § 6 for migration patterns.
|
|
99
|
+
|
|
100
|
+
### Per-feature param shape
|
|
101
|
+
|
|
102
|
+
These types changed shape (typically: gained a generic `<K extends SpokeChainKey>`, gained `srcChainKey` and `srcAddress` required fields). The v1 names still exist but with a different signature — fixing imports won't compile, you also need to update construction.
|
|
103
|
+
|
|
104
|
+
| v1 type | v2 type | Required additions in v2 |
|
|
105
|
+
|---|---|---|
|
|
106
|
+
| `MoneyMarketSupplyParams` | `MoneyMarketSupplyParams<K extends SpokeChainKey>` | `srcChainKey: K`, `srcAddress: GetAddressType<K>` |
|
|
107
|
+
| `MoneyMarketBorrowParams` | `MoneyMarketBorrowParams<K>` | Same; plus optional `dstChainKey`, `dstAddress` for cross-chain. |
|
|
108
|
+
| `MoneyMarketWithdrawParams` | `MoneyMarketWithdrawParams<K>` | Same. |
|
|
109
|
+
| `MoneyMarketRepayParams` | `MoneyMarketRepayParams<K>` | Same; plus optional `dstChainKey`/`dstAddress` (debt chain). |
|
|
110
|
+
| `StakeParams`, `UnstakeParams`, `InstantUnstakeParams`, `ClaimParams`, `CancelUnstakeParams` | All gained `<K>` generic | `srcChainKey: K`, `srcAddress: GetAddressType<K>`. v1 `account` field renamed to `srcAddress`. |
|
|
111
|
+
| `MigrationParams` | `MigrationParams<K>` | Same. |
|
|
112
|
+
| `UnifiedBnUSDMigrateParams` | `UnifiedBnUSDMigrateParams<K>` | Same. |
|
|
113
|
+
| `CreateAssetDepositParams`, `CreateAssetWithdrawParams`, `ClSupplyParams`, `ClIncreaseLiquidityParams`, `ClDecreaseLiquidityParams`, `ClClaimRewardsParams` | All gained `<K>` generic | `srcChainKey`, `srcAddress`. |
|
|
114
|
+
| `CreateIntentParams`, `CreateLimitOrderParams` | All gained `<K>` generic | Field renames `srcChain` → `srcChainKey`, `dstChain` → `dstChainKey` (v1 `srcChain` was a chain id type, now `srcChainKey: K`). |
|
|
115
|
+
|
|
116
|
+
The [`error TS1360`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-2.html#smarter-type-alias-preservation) pattern (`Type '{ token, amount, action }' does not satisfy the expected type 'MoneyMarketSupplyParams'`) is the typecheck signature: a literal that matches v1's shape but missing v2's required `srcChainKey` and `srcAddress`. Add both.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
## Cross-references
|
|
122
|
+
|
|
123
|
+
- [`README.md`](README.md) — migration reference index.
|
|
124
|
+
- [`../README.md`](../README.md) — migration overview.
|
|
125
|
+
- [`../checklist.md`](../checklist.md) — top-level migration checklist.
|
|
126
|
+
- [`../breaking-changes/architecture.md`](../breaking-changes/architecture.md) § 2 — guidance for v1 static constants that are still exported in v2.
|