@sodax/sdk 1.5.6-beta → 2.0.0-rc.1

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 (57) hide show
  1. package/README.md +91 -7
  2. package/ai-exported/AGENTS.md +99 -0
  3. package/ai-exported/integration/README.md +41 -0
  4. package/ai-exported/integration/ai-rules.md +75 -0
  5. package/ai-exported/integration/architecture.md +519 -0
  6. package/ai-exported/integration/chain-specifics.md +189 -0
  7. package/ai-exported/integration/features/README.md +19 -0
  8. package/ai-exported/integration/features/auxiliary-services.md +189 -0
  9. package/ai-exported/integration/features/bridge.md +136 -0
  10. package/ai-exported/integration/features/dex.md +182 -0
  11. package/ai-exported/integration/features/icx-bnusd-baln.md +181 -0
  12. package/ai-exported/integration/features/money-market.md +198 -0
  13. package/ai-exported/integration/features/staking.md +166 -0
  14. package/ai-exported/integration/features/swap.md +207 -0
  15. package/ai-exported/integration/quickstart.md +213 -0
  16. package/ai-exported/integration/recipes/README.md +21 -0
  17. package/ai-exported/integration/recipes/backend-server-init.md +69 -0
  18. package/ai-exported/integration/recipes/chain-key-narrowing.md +65 -0
  19. package/ai-exported/integration/recipes/gas-estimation.md +33 -0
  20. package/ai-exported/integration/recipes/initialize-sodax.md +53 -0
  21. package/ai-exported/integration/recipes/raw-tx-flow.md +71 -0
  22. package/ai-exported/integration/recipes/result-and-errors.md +104 -0
  23. package/ai-exported/integration/recipes/signed-tx-flow.md +46 -0
  24. package/ai-exported/integration/recipes/testing.md +101 -0
  25. package/ai-exported/integration/reference/README.md +18 -0
  26. package/ai-exported/integration/reference/chain-keys.md +67 -0
  27. package/ai-exported/integration/reference/error-codes.md +165 -0
  28. package/ai-exported/integration/reference/glossary.md +32 -0
  29. package/ai-exported/integration/reference/public-api.md +138 -0
  30. package/ai-exported/integration/reference/wallet-providers.md +62 -0
  31. package/ai-exported/migration/README.md +58 -0
  32. package/ai-exported/migration/ai-rules.md +80 -0
  33. package/ai-exported/migration/breaking-changes/architecture.md +335 -0
  34. package/ai-exported/migration/breaking-changes/result-and-errors.md +363 -0
  35. package/ai-exported/migration/breaking-changes/type-system.md +321 -0
  36. package/ai-exported/migration/checklist.md +61 -0
  37. package/ai-exported/migration/features/README.md +35 -0
  38. package/ai-exported/migration/features/auxiliary-services.md +156 -0
  39. package/ai-exported/migration/features/bridge.md +125 -0
  40. package/ai-exported/migration/features/dex.md +143 -0
  41. package/ai-exported/migration/features/icx-bnusd-baln.md +151 -0
  42. package/ai-exported/migration/features/money-market.md +214 -0
  43. package/ai-exported/migration/features/staking.md +138 -0
  44. package/ai-exported/migration/features/swap.md +198 -0
  45. package/ai-exported/migration/recipes.md +288 -0
  46. package/ai-exported/migration/reference/README.md +18 -0
  47. package/ai-exported/migration/reference/deleted-exports.md +100 -0
  48. package/ai-exported/migration/reference/error-code-crosswalk.md +104 -0
  49. package/ai-exported/migration/reference/return-shapes.md +49 -0
  50. package/ai-exported/migration/reference/sodax-config.md +52 -0
  51. package/dist/index.cjs +32154 -31601
  52. package/dist/index.cjs.map +1 -1
  53. package/dist/index.d.cts +8442 -6974
  54. package/dist/index.d.ts +8442 -6974
  55. package/dist/index.mjs +32642 -32130
  56. package/dist/index.mjs.map +1 -1
  57. package/package.json +19 -11
package/README.md CHANGED
@@ -40,41 +40,55 @@ How to setup local development
40
40
 
41
41
  <a href="https://docs.sodax.com/developers/packages/sdk/swaps" class="button secondary" data-icon="rotate">Swaps (Solver)</a> - Cross-chain intent-based swaps
42
42
 
43
- * EVM (Arbitrum, Avalanche, Base, BSC, Optimism, Polygon, Sonic, HyperEVM, Lightlink) ✅
43
+ * EVM (Sonic, Ethereum, Arbitrum, Avalanche, Base, BSC, Optimism, Polygon, HyperEVM, Lightlink, Redbelly, Kaia) ✅
44
44
  * Sui ✅
45
45
  * Stellar ✅
46
46
  * ICON ✅
47
47
  * Solana ✅
48
48
  * Injective ✅
49
+ * NEAR ✅
50
+ * Stacks ✅
51
+ * Bitcoin ✅
49
52
 
50
53
  <a href="https://docs.sodax.com/developers/packages/sdk/money_market" class="button secondary" data-icon="sack-dollar">Lend / Borrow (Money Market)</a>- Cross-chain lending and borrowing
51
54
 
52
- * EVM (Arbitrum, Avalanche, Base, BSC, Optimism, Polygon, Sonic, HyperEVM, Lightlink) ✅
55
+ * EVM (Sonic, Ethereum, Arbitrum, Avalanche, Base, BSC, Optimism, Polygon, HyperEVM, Lightlink, Redbelly, Kaia) ✅
53
56
  * Sui ✅
54
57
  * Stellar ✅
55
- * ICON ✅
58
+ * ICON ✅ (bnUSD only)
56
59
  * Solana ✅
57
60
  * Injective ✅
61
+ * NEAR ✅
62
+ * Stacks ✅
63
+ * Bitcoin ✅ (BTC only)
58
64
 
59
65
  <a href="https://docs.sodax.com/developers/packages/sdk/bridge" class="button secondary" data-icon="bridge-suspension">Bridge</a>- Cross-chain token bridging
60
66
 
61
- * EVM (Arbitrum, Avalanche, Base, BSC, Optimism, Polygon, Sonic, HyperEVM, Lightlink) ✅
67
+ * EVM (Sonic, Ethereum, Arbitrum, Avalanche, Base, BSC, Optimism, Polygon, HyperEVM, Lightlink, Redbelly, Kaia) ✅
62
68
  * Sui ✅
63
69
  * Stellar ✅
64
70
  * ICON ✅
65
71
  * Solana ✅
66
72
  * Injective ✅
73
+ * NEAR ✅
74
+ * Stacks ✅
75
+ * Bitcoin ✅
67
76
 
68
77
  <a href="https://docs.sodax.com/developers/packages/sdk/migration" class="button secondary" data-icon="truck">Migration</a>- Token migration (ICX, bnUSD, BALN)
69
78
 
79
+ * ICX / wICX → SODA: source chain ICON only
80
+ * BALN → SODA: source chain ICON only
81
+ * bnUSD: between legacy chains (ICON, Sui, Stellar) and the new bnUSD on any other supported chain
82
+
70
83
  <a href="https://docs.sodax.com/developers/packages/sdk/staking" class="button secondary" data-icon="seedling">Staking</a>- SODA token staking
71
84
 
72
- * EVM (Arbitrum, Avalanche, Base, BSC, Optimism, Polygon, Sonic, HyperEVM, Lightlink) ✅
85
+ * EVM (Sonic, Ethereum, Arbitrum, Avalanche, Base, BSC, Optimism, Polygon, HyperEVM, Lightlink, Redbelly, Kaia) ✅
73
86
  * Sui ✅
74
87
  * Stellar ✅
75
- * ICON ✅
76
88
  * Solana ✅
77
89
  * Injective ✅
90
+ * NEAR ✅
91
+ * Stacks ✅
78
92
 
79
93
  ### Tooling Modules inside the SDK
80
94
 
@@ -82,6 +96,76 @@ How to setup local development
82
96
 
83
97
  <a href="https://docs.sodax.com/developers/packages/sdk/intent_relay_api" class="button secondary" data-icon="envelope">Intent Relay API</a>- Relayer API endpoint documentation
84
98
 
99
+ ## AI agent docs
100
+
101
+ `@sodax/sdk` ships an AI-ready documentation tree at `node_modules/@sodax/sdk/ai-exported/`. It's tool-neutral: any agent that can read files (Claude Code, Cursor, Aider, Copilot Chat, ChatGPT with file context, etc.) can use it without further setup.
102
+
103
+ ### Get started
104
+
105
+ Point your agent at `node_modules/@sodax/sdk/ai-exported/AGENTS.md` — it routes to the rest. Three sample prompts covering the typical entry points:
106
+
107
+ ```
108
+ > Read node_modules/@sodax/sdk/ai-exported/AGENTS.md and integrate
109
+ > SODAX cross-chain swaps from Arbitrum to Stellar into my Node service.
110
+
111
+ > Read node_modules/@sodax/sdk/ai-exported/AGENTS.md. My code uses
112
+ > @sodax/sdk v1 — port my call sites to v2.
113
+
114
+ > Look up the v2 SodaxError code for a relay timeout in
115
+ > node_modules/@sodax/sdk/ai-exported/integration/reference/error-codes.md.
116
+ ```
117
+
118
+ ### What's inside
119
+
120
+ ```
121
+ ai-exported/
122
+ ├── AGENTS.md # Tool-neutral entry point — start here
123
+ ├── integration/ # Building NEW v2 code
124
+ │ ├── README.md, ai-rules.md # Index + DO / DO NOT / workflow for agents
125
+ │ ├── quickstart.md # Install + initialize + first-run troubleshooting
126
+ │ ├── architecture.md # Type system + design concepts (Result, ChainKeys, …)
127
+ │ ├── chain-specifics.md # Non-EVM quirks (Stellar, BTC, Solana, ICON, NEAR)
128
+ │ ├── features/ # 7 feature pages: swap, money-market, staking, bridge,
129
+ │ │ # dex, icx-bnusd-baln, auxiliary-services
130
+ │ ├── recipes/ # 8 copy-pasteable patterns: init, signed-/raw-tx flow,
131
+ │ │ # error handling, narrowing, testing, gas, backend init
132
+ │ └── reference/ # 5 lookup tables: chain keys, wallet providers,
133
+ │ # error codes, public API surface, glossary
134
+ └── migration/ # Porting EXISTING v1 code to v2
135
+ ├── README.md, ai-rules.md # Index + workflow for porting agents
136
+ ├── checklist.md # 17-step cross-cutting checklist
137
+ ├── breaking-changes/ # 3 cross-cutting changes: type-system, architecture,
138
+ │ # result-and-errors
139
+ ├── features/ # 7 per-feature porting playbooks (same names as
140
+ │ # integration/features/)
141
+ ├── recipes.md # Codemods + error-shape and Result adapters
142
+ └── reference/ # 4 reference tables: deleted exports, sodax-config
143
+ # reshape, error-code crosswalk, return-shape diffs
144
+ ```
145
+
146
+ ### Scope
147
+
148
+ This tree documents `@sodax/sdk` (the Core SDK) only. It assumes:
149
+
150
+ - **TypeScript** — examples are TS; the SDK ships dual ESM/CJS.
151
+ - **Runtime-agnostic** — Node.js, browsers, bundled apps. **No React or Next.js content** — the SDK is UI-framework-agnostic and the docs reflect that.
152
+ - **`@sodax/types` is re-exported** through `@sodax/sdk`'s barrel; consumers don't add it as a separate dependency.
153
+
154
+ `@sodax/wallet-sdk-core` is **mentioned** in a few places as a pointer — it's a separate SODAX package that ships ready-made `I*WalletProvider` implementations for all 9 chain families. Consumers can install it separately or implement the wallet-provider interfaces themselves. React-layer packages (`@sodax/wallet-sdk-react`, `@sodax/dapp-kit`) are **out of scope here** and may have their own `ai-exported/` trees in their respective packages.
155
+
156
+ ### Integrity guarantees
157
+
158
+ Every release passes four CI checks against `ai-exported/`:
159
+
160
+ | Guard | What it catches |
161
+ |---|---|
162
+ | `check:ai-exported` | Each top-level `sodax.X` reference matches a real public member of the `Sodax` class in `src/shared/entities/Sodax.ts`. (Shallow — `sodax.partners.invented` would still pass.) |
163
+ | `check:ai-scope` | No accidental sibling-package, React, or Next.js content leaks in. |
164
+ | `check:ai-links` | Every relative link between markdown files resolves. |
165
+ | `check:ai-imports` | Every `import … from '@sodax/sdk'` example in the docs typechecks against the SDK source. |
166
+
167
+ If you're contributing to this repo, run them with `pnpm -C packages/sdk run check:ai-exported` (or `:scope`, `:links`, `:imports`).
168
+
85
169
  ***
86
170
 
87
171
  ## Contributing
@@ -122,5 +206,5 @@ pnpm lint
122
206
 
123
207
  ## Support
124
208
 
125
- * [GitHub Issues](https://github.com/icon-project/sodax-frontend/issues)
209
+ * [GitHub Issues](https://github.com/icon-project/sodax-sdks/issues)
126
210
  * [Discord Community](https://discord.gg/xM2Nh4S6vN)
@@ -0,0 +1,99 @@
1
+ # AGENTS.md — `@sodax/sdk` v2
2
+
3
+ > Tool-neutral entry point for any AI coding agent assisting a consumer of `@sodax/sdk`. If you're at `node_modules/@sodax/sdk/ai-exported/AGENTS.md`, you are in the right place — everything you need is reachable from here without leaving the npm tarball.
4
+
5
+ ## Project
6
+
7
+ `@sodax/sdk` is the official SDK for SODAX, a cross-chain DeFi platform built on a hub-and-spoke architecture (Sonic is the hub; 19 spoke chains across EVM and non-EVM ecosystems). The SDK provides cross-chain swaps (intent-based via solver), lending/borrowing (money market), staking, bridging, concentrated-liquidity DEX, ICX/bnUSD/BALN migration, and partner-fee operations. It is runtime-agnostic and runs in Node.js, browsers, and bundled apps.
8
+
9
+ This package is **v2**. v2 was a deep architectural reshape of v1 — chain-key driven routing replaced per-chain provider classes; `Result<T>` replaced throwing methods; `SodaxError<C>` replaced module-specific error unions; `WalletProviderSlot<K, Raw>` replaced ad-hoc wallet/raw branching; `ConfigService` replaced static lookup tables. Code written against v1 will not compile against v2.
10
+
11
+ ## When to read what
12
+
13
+ ```
14
+ Are you writing NEW code against v2? → integration/ai-rules.md, then integration/
15
+ Are you porting EXISTING v1 code to v2? → migration/ai-rules.md, then migration/
16
+ Just need a chain key / error code / type? → integration/reference/
17
+ Need to install + initialize the SDK? → integration/quickstart.md
18
+ Hit a non-EVM chain quirk (Stellar, BTC, …)? → integration/chain-specifics.md
19
+ ```
20
+
21
+ If a consumer's repo has both v1 call sites and a request to extend with new code, do migration first. Stale v1 patterns leak into new code if you skip it.
22
+
23
+ **Always start with the `ai-rules.md` for the tree you're working in** — it's the consolidated DO / DO NOT / workflow / stop-conditions guide that prevents the most common v2 traps. Read it once, then dive into the per-feature docs.
24
+
25
+ ## Top-level layout
26
+
27
+ ```
28
+ ai-exported/
29
+ ├── AGENTS.md # You are here
30
+ ├── integration/ # How to use v2 (new consumers)
31
+ │ ├── README.md # Index for this tree
32
+ │ ├── ai-rules.md # DO / DO NOT / workflow — read before per-feature docs
33
+ │ ├── quickstart.md # Install + initialize + first-run troubleshooting
34
+ │ ├── architecture.md # Every v2 design concept (TOC-navigable)
35
+ │ ├── features/ # One file per feature service
36
+ │ │ ├── README.md
37
+ │ │ ├── swap.md
38
+ │ │ ├── money-market.md
39
+ │ │ ├── staking.md
40
+ │ │ ├── bridge.md
41
+ │ │ ├── dex.md
42
+ │ │ ├── icx-bnusd-baln.md # MigrationService (the SDK module, not the v1→v2 port)
43
+ │ │ └── auxiliary-services.md # PartnerService + RecoveryService + BackendApiService
44
+ │ ├── recipes/ # One file per pattern — init, result/errors, raw, signed, narrowing, testing, gas, backend-init
45
+ │ ├── reference/ # One file per table — chain keys, wallet providers, error codes, public API, glossary
46
+ │ └── chain-specifics.md # Non-EVM quirks (Stellar trustline, BTC PSBT, Solana PDA, ICON, NEAR)
47
+ └── migration/ # How to port v1 → v2
48
+ ├── README.md # Overview + reading order + cross-cutting checklist + v1↔v2 glossary
49
+ ├── ai-rules.md # DO / DO NOT / workflow for porting agents
50
+ ├── breaking-changes/ # Cross-cutting v1→v2 changes
51
+ │ ├── type-system.md # @sodax/types renames + ChainKeys + WalletProviderSlot + RpcConfig + IConfigApi Result
52
+ │ ├── architecture.md # *SpokeProvider deletion + ConfigService + relay reshape + invariants
53
+ │ └── result-and-errors.md # Throws → Result<T>; module errors → SodaxError<C>; v1↔v2 code crosswalk; return shapes
54
+ ├── features/ # Per-feature pure-SDK migration playbooks
55
+ │ ├── README.md
56
+ │ ├── swap.md, money-market.md, staking.md, bridge.md, dex.md, icx-bnusd-baln.md, auxiliary-services.md
57
+ └── recipes.md # Codemods + error-shape adapter + result adapter
58
+ ```
59
+
60
+ ## v2 in one minute
61
+
62
+ 1. **Chain key drives everything.** Pass `srcChainKey: ChainKeys.ETHEREUM_MAINNET` (or any of 20 keys) on the request payload. The SDK routes to the correct per-chain spoke service internally and TypeScript narrows the wallet-provider parameter to the chain-specific interface via `GetWalletProviderType<K>`. There are **no** `*SpokeProvider` classes to construct.
63
+ 2. **Every async public method returns `Result<T>`.** Branch on `result.ok`. No throws across service boundaries. Sub-Result forwarding is the default: `if (!sub.ok) return sub`.
64
+ 3. **Errors are `SodaxError<C>`.** A single class with a closed 13-code reason vocabulary (`VALIDATION_FAILED`, `RELAY_TIMEOUT`, `EXECUTION_FAILED`, …) plus a `feature` field (`'swap' | 'moneyMarket' | …`). The pair `(feature, code)` is your discriminator. Use `isSodaxError(e)` (not bare `instanceof`).
65
+ 4. **Signed vs raw is a discriminated union.** `WalletProviderSlot<K, Raw>` enforces at compile time: `{ raw: false, walletProvider: <chain-narrowed> }` for signing, `{ raw: true }` for unsigned-tx building. Mixing them is a TypeScript error.
66
+ 5. **Config is dynamic.** `await sodax.config.initialize()` fetches current chain/token config from the backend, with a safe fallback to packaged defaults. Lookups go through `sodax.config.*` — there is no `hubAssets`, no `moneyMarketSupportedTokens` global map, no static registry to import.
67
+
68
+ ## Top 5 v1 → v2 traps
69
+
70
+ 1. **Reaching for a `*SpokeProvider`.** They're deleted. Pass an object satisfying the chain-specific `I*WalletProvider` interface (e.g. `IEvmWalletProvider`) directly into the SDK call payload. Implementations come from your application — write your own to satisfy the interface, or install `@sodax/wallet-sdk-core` (a separate SODAX package, not bundled into `@sodax/sdk`) for ready-made implementations. The chain key on the payload is what routes — there is no provider class for `@sodax/sdk` consumers to instantiate.
71
+ 2. **Forgetting `raw: false`.** Without the discriminator, `walletProvider` is rejected with "Object literal may only specify known properties, and 'walletProvider' does not exist in type". Add `raw: false` for signed flows; `raw: true` for unsigned-tx building.
72
+ 3. **Importing from `@sodax/types` directly.** `@sodax/sdk` re-exports the entire `@sodax/types` surface via its barrel. Add `@sodax/sdk` as your only dependency; importing `@sodax/types` separately risks version skew.
73
+ 4. **Treating `Result<T>` as throw-on-failure.** v2 mutation methods do **not** throw on SDK-level failure — they resolve `{ ok: false, error }`. A `try { await sodax.<method>(...) } catch` only catches *exceptions* from inside `mutationFn` (e.g. missing `walletProvider`); it will **not** catch `RELAY_TIMEOUT` or `EXECUTION_FAILED`. Branch on `.ok`.
74
+ 5. **Reading `xToken.xChainId` or hard-coding `*_MAINNET_CHAIN_ID`.** Renamed: `XToken.chainKey` and `ChainKeys.*`. v1 numeric/string chain-id constants are gone. `ChainKeys.ICON_MAINNET` is `'0x1.icon'` (a string), not the legacy numeric ID — `Number(chainKey)` returns `NaN`.
75
+
76
+ See `migration/README.md` for the complete trap list and `migration/breaking-changes/` for full v1↔v2 detail.
77
+
78
+ ## Public API contract
79
+
80
+ - Import only from the package root: `import { Sodax, ChainKeys, type SpokeChainKey } from '@sodax/sdk'`.
81
+ - Do **not** add `@sodax/types` to your dependencies — `@sodax/sdk` re-exports the full types surface (`export * from '@sodax/types'` from the barrel). Importing `@sodax/types` separately is unsupported and may silently version-skew.
82
+ - Do **not** deep-import from `dist/...`. Internal paths are not stable across releases. Anything intended for consumer use is exported from the root.
83
+ - The published tarball ships `dist/` and `ai-exported/`. Do not rely on any other path being present.
84
+
85
+ ## Conventions agents must follow
86
+
87
+ - **`Result<T>` discrimination on `.ok`.** Always branch on `result.ok` before reading `.value` or `.error`. Forward sub-Results without re-wrapping (`if (!sub.ok) return sub`).
88
+ - **`(feature, code)` for error switching.** Use `isSodaxError(e)`, then `e.feature` and `e.code` for routing logic. Don't string-match on `e.message`.
89
+ - **`ChainKeys.*` over hard-coded strings.** Use `ChainKeys.ETHEREUM_MAINNET`, not `'eth'` / `'0xa86a.fuji'`. The set of supported chains evolves per release.
90
+ - **No `as unknown as <Type>` double-casts.** v2 type narrowing makes them unnecessary in 99% of cases — chain-key generic flow + `GetWalletProviderType<K>` resolves to the exact interface. If a cast feels needed, look for the chain-key narrowing pattern in `integration/recipes/` first.
91
+ - **Conventional commits if generating commits** in the consumer repo (`feat:`, `fix:`, `chore:`). Many SODAX-adjacent repos enforce this via commitlint.
92
+ - **Don't generate `try { await sodax.<method>(...) } catch` for SDK-level failures.** That catch never fires for `Result` `!ok`. Branch on `result.ok`.
93
+
94
+ ## Pointers
95
+
96
+ - `integration/README.md` — start here for any new v2 work.
97
+ - `migration/README.md` — start here for any v1 → v2 port.
98
+ - `integration/quickstart.md` — install, initialize, first-run troubleshooting.
99
+ - `integration/reference/` — chain key table, error code table, public API surface, glossary.
@@ -0,0 +1,41 @@
1
+ # Integration — `@sodax/sdk` v2
2
+
3
+ This tree documents v2 of the SDK for **new consumers** building against it. If you're porting v1 code, start at [`../migration/README.md`](../migration/README.md) instead.
4
+
5
+ ## Files in this tree
6
+
7
+ | File | What's in it |
8
+ |---|---|
9
+ | [`quickstart.md`](quickstart.md) | Install, initialize a `Sodax` instance, and the top init/setup errors and how to fix them. Covers reads (no wallet), raw-tx flows (no wallet), and signed flows (consumer-supplied wallet provider). |
10
+ | [`architecture.md`](architecture.md) | Every v2 design concept the SDK rests on, in a single TOC-navigable file: hub-and-spoke model, `SpokeService` router, `Sodax` facade + `ConfigService`, `ChainKeys`, `WalletProviderSlot<K, Raw>`, `Result<T>`, `SodaxError<C>` + 13-code vocabulary, relay layer (`mapRelayFailure`, `relayTxAndWaitPacket`). |
11
+ | [`features/swap.md`](features/swap.md) | `SwapService`: intent-based swaps via the solver — `createIntent`, `swap`, `postExecution`, limit orders, `cancelIntent`. |
12
+ | [`features/money-market.md`](features/money-market.md) | `MoneyMarketService`: cross-chain lending/borrowing — supply, borrow, withdraw, repay, reserves, allowance. |
13
+ | [`features/staking.md`](features/staking.md) | `StakingService`: SODA → xSoda — stake, unstake, instant unstake, claim, cancel; ratio + info reads. |
14
+ | [`features/bridge.md`](features/bridge.md) | `BridgeService`: cross-chain token transfer via vault — `bridge`, `createBridgeIntent`, `getBridgeableAmount`, `getBridgeableTokens`. |
15
+ | [`features/dex.md`](features/dex.md) | `ClService` (concentrated liquidity) + `AssetService`: position lifecycle (mint/increase/decrease), claim rewards, asset deposit/withdraw. |
16
+ | [`features/icx-bnusd-baln.md`](features/icx-bnusd-baln.md) | `MigrationService` (the SDK module): ICX, bnUSD, BALN sub-services + lock management. |
17
+ | [`features/auxiliary-services.md`](features/auxiliary-services.md) | `PartnerService` + `RecoveryService` + `BackendApiService` — small APIs grouped together. |
18
+ | [`recipes/`](recipes/) | Copy-pasteable patterns: SDK initialization, `Result` + error discrimination, raw-tx flow, signed-tx flow, chain-key narrowing + cast-at-boundary, testing (mocks/stubs), gas estimation, backend-server init. |
19
+ | [`reference/`](reference/) | Lookup tables: 20-chain `ChainKeys` table with family + relay id, `I*WalletProvider` interfaces, 13 `SodaxErrorCode` meanings + per-feature narrow unions, public API surface (incl. `@sodax/types` re-export rule), glossary. |
20
+ | [`chain-specifics.md`](chain-specifics.md) | Non-EVM quirks — Stellar trustline check/request, Bitcoin PSBT + Radfi auth/session, Solana PDA derivation, ICON Hana wallet + chain-key string, NEAR connector discovery. |
21
+
22
+ ## Reading order for a new integrator
23
+
24
+ 1. `quickstart.md` — get the SDK installed and a `Sodax` instance running.
25
+ 2. `architecture.md` — understand the type system (`ChainKeys`, `Result`, `WalletProviderSlot`, `SodaxError`) before writing call sites.
26
+ 3. `recipes/` — pick the patterns you need (signed vs raw, error handling, narrowing).
27
+ 4. `features/<x>.md` — read the file for the feature you're integrating.
28
+ 5. `chain-specifics.md` — only if you target a non-EVM chain; skip otherwise.
29
+ 6. `reference/` — keep open while writing for table lookups.
30
+
31
+ ## Cross-references to migration
32
+
33
+ If your project also has v1 call sites, port them first using:
34
+
35
+ - [`../migration/README.md`](../migration/README.md) — overview, reading order, and cross-cutting checklist.
36
+ - [`../migration/breaking-changes/type-system.md`](../migration/breaking-changes/type-system.md) — type renames and shape changes you'll hit on import.
37
+ - [`../migration/breaking-changes/architecture.md`](../migration/breaking-changes/architecture.md) — `*SpokeProvider` deletion, `ConfigService` replacing static lookups, relay flow reshape.
38
+ - [`../migration/breaking-changes/result-and-errors.md`](../migration/breaking-changes/result-and-errors.md) — throws → `Result<T>` and module errors → `SodaxError<C>`, with the v1↔v2 code crosswalk.
39
+ - [`../migration/features/`](../migration/features/) — per-feature playbooks in lockstep with the integration features here.
40
+
41
+ The naming rule: **every feature in `integration/features/` has a sibling in `migration/features/` with the same filename.** When you're deep in one, the other is one path-swap away.
@@ -0,0 +1,75 @@
1
+ # AI rules — `@sodax/sdk` integration
2
+
3
+ DO / DO NOT / workflow / stop conditions for AI agents writing `@sodax/sdk` v2 code. Read this **before** the per-feature docs — these rules are how you avoid the load-bearing v2 traps.
4
+
5
+ ## Workflow (do these in order)
6
+
7
+ 1. **Survey the project before touching code.**
8
+
9
+ ```bash
10
+ pnpm tsc --noEmit # baseline typecheck
11
+ grep -rE '@sodax/(sdk|types)' --include='*.ts' --include='*.tsx' src/ # see what's already imported
12
+ ```
13
+
14
+ 2. **Always initialize first.** `new Sodax()` constructs the facade; `await sodax.config.initialize()` loads chain/token config from the backend (with packaged-defaults fallback). Skipping `initialize()` works but means stale defaults — `findSupportedTokenBySymbol` may return `undefined` for tokens added after the SDK release.
15
+ 3. **Pick `raw: true` vs `raw: false` explicitly.** Reads and unsigned-tx-building flows take `raw: true` and don't need a wallet. Signed flows take `raw: false` + a chain-narrowed `walletProvider`. The discriminator is mandatory — without it the type system rejects the call. See [`architecture.md`](architecture.md) § 6.
16
+ 4. **Branch on `result.ok` before reading `.value` or `.error`.** Every async public method returns `Promise<Result<T, SodaxError>>`. `try/catch` does **not** catch SDK-level failures — see DO NOT § below.
17
+ 5. **Discriminate errors by `(error.feature, error.code)`.** Use `isSodaxError(e)` first, then switch on the pair. Don't string-match `error.message`.
18
+
19
+ ## DO
20
+
21
+ - **DO** branch on `result.ok` for every SDK call. Forward sub-`Result`s without re-wrapping (`if (!sub.ok) return sub`).
22
+ - **DO** use `isSodaxError(e)` over bare `instanceof SodaxError`. Bundle-safe in cross-realm code (mixed ESM/CJS, monorepos with multiple package copies).
23
+ - **DO** discriminate errors via `(error.feature, error.code)`. The narrow per-method code unions (e.g. `CreateSupplyIntentErrorCode`) enable exhaustive `switch`.
24
+ - **DO** use `ChainKeys.X` constants for chain identifiers. Never hard-code chain-key string values like `'ethereum'` or `'0xa4b1.arbitrum'`.
25
+ - **DO** use `declare const xxxWallet: I*WalletProvider` placeholders in code examples or generated docs. Implementations are not part of `@sodax/sdk`; substitute the consumer's own wallet object at the call site.
26
+ - **DO** import everything from `@sodax/sdk` root. Types from `@sodax/types` are re-exported.
27
+ - **DO** preserve literal chain keys in generic positions where possible (e.g. `srcChainKey: ChainKeys.ETHEREUM_MAINNET as const`) — TypeScript narrowing flows from the literal, including the `walletProvider` parameter type.
28
+
29
+ ## DO NOT
30
+
31
+ - **DO NOT** wrap `await sodax.<method>(...)` in `try/catch` and expect SDK-level failures (`RELAY_TIMEOUT`, `EXECUTION_FAILED`, etc.) to land there. They don't — the SDK resolves `{ ok: false, error }` instead of throwing. `catch` only fires for synchronous wrapper exceptions.
32
+ - **DO NOT** import from `@sodax/sdk/dist/...`. Deep imports are unstable across releases; only the package root barrel is the public contract.
33
+ - **DO NOT** add `@sodax/types` as a separate dependency. It's bundled / re-exported via `@sodax/sdk`. Adding it independently invites version skew.
34
+ - **DO NOT** destructure cross-chain mutation results as arrays — `[a, b] = result.value` is wrong. The shape is `TxHashPair = { srcChainTxHash, dstChainTxHash }` (object). This applies to `bridge.bridge`, `staking.{stake,unstake,instantUnstake,claim,cancelUnstake}`, `dex.assetService.{deposit,withdraw}`, `dex.clService.{supplyLiquidity,increaseLiquidity,decreaseLiquidity,claimRewards}`, `moneyMarket.{supply,borrow,withdraw,repay}`, `migration.{migratebnUSD,migrateIcxToSoda,revertMigrateSodaToIcx,migrateBaln}` — all of them.
35
+ - **DO NOT** treat method names from `MoneyMarketService` as the source of MM reads. `getReservesData`, `getUserReservesData`, `getATokensBalances`, etc. live on `sodax.backendApi`, not `sodax.moneyMarket`. See [`features/auxiliary-services.md`](features/auxiliary-services.md) § "BackendApiService".
36
+ - **DO NOT** reach for an `intentRelayApi` property on the `Sodax` instance — there is no such property. The relay layer is exposed as two top-level functions, `relayTxAndWaitPacket` and `submitTransaction` (re-exported from `@sodax/sdk`). Call them directly if you need custom relay orchestration.
37
+ - **DO NOT** call `getStakeRatio` and treat its return as `Result<bigint>`. It's `Result<[xSodaAmount, previewDepositAmount]>` — a tuple of two bigints.
38
+ - **DO NOT** assume `BalnSwapService` lock-management methods (`stake`, `unstake`, `claim`, `claimUnstaked`, `cancelUnstake`, `getDetailedUserLocks`) return `Result<T>`. They still throw on error in v2 — known carve-out. Wrap them in `try/catch`.
39
+ - **DO NOT** call methods that need a wallet provider with `raw: true` — TypeScript rejects `walletProvider` when `raw: true`. Use `raw: false` + `walletProvider`, or stick to read methods.
40
+
41
+ ## Stop conditions (defer to user)
42
+
43
+ | Signal | Why stop |
44
+ |---|---|
45
+ | User wants a chain not in `ChainKeys.*` | Adding a new chain requires SDK-level changes to `@sodax/types`/`@sodax/sdk` — out of scope for consumer code. |
46
+ | User wants to skip `await sodax.config.initialize()` | Explain consequences: stale defaults, no awareness of new tokens / fee parameters. Don't silently skip. |
47
+ | User code expects sibling-package imports (e.g. `@sodax/wallet-sdk-core` instances) | Out of scope here — consumer owns the wallet-provider implementation. Document the `I*WalletProvider` shape they need to satisfy or instruct them to install `@sodax/wallet-sdk-core` separately and refer to that package's docs. |
48
+ | User wants browser-extension wallet wiring inside SDK code | Not the SDK's concern. Consumer owns the wallet layer. |
49
+
50
+ ## Verification protocol
51
+
52
+ Before declaring an SDK integration "done":
53
+
54
+ ```bash
55
+ # 1. Type-check the consumer.
56
+ pnpm -C <consumer> tsc --noEmit
57
+
58
+ # 2. Confirm no leftover v1 patterns (if porting).
59
+ grep -rE '_MAINNET_CHAIN_ID\b|\bxChainId\b|\bSpokeChainId\b|\bSpokeProvider\b' src/
60
+
61
+ # 3. Confirm Result branching is in place.
62
+ grep -rE 'await sodax\.\w+\.\w+\([^)]*\)' src/ | grep -v '\.ok\|\.value\|\.error' # any SDK call without result.ok / value / error in nearby lines
63
+
64
+ # 4. Smoke-test a read flow before a signed flow.
65
+ # sodax.config.findSupportedTokenBySymbol(...) etc. — no wallet needed.
66
+ ```
67
+
68
+ ## Done criteria
69
+
70
+ - [ ] `await sodax.config.initialize()` runs at app startup (or before first feature call).
71
+ - [ ] Every `await sodax.<feature>.<method>(...)` is followed by `if (!result.ok)` branching.
72
+ - [ ] No `try/catch` wraps SDK calls expecting to catch `RELAY_TIMEOUT` / `EXECUTION_FAILED`.
73
+ - [ ] No `import` from `@sodax/sdk/dist/...`.
74
+ - [ ] No standalone `@sodax/types` dependency in `package.json`.
75
+ - [ ] Consumer typecheck (`pnpm tsc --noEmit`) is clean.