@sodax/skills 2.0.0-rc.10
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/.claude-plugin/plugin.json +18 -0
- package/AGENTS.md +83 -0
- package/LICENSE +21 -0
- package/README.md +49 -0
- package/package.json +58 -0
- package/skills/sodax-dapp-kit/SKILL.md +129 -0
- package/skills/sodax-dapp-kit/integration/knowledge/README.md +49 -0
- package/skills/sodax-dapp-kit/integration/knowledge/ai-rules.md +80 -0
- package/skills/sodax-dapp-kit/integration/knowledge/architecture.md +276 -0
- package/skills/sodax-dapp-kit/integration/knowledge/features/README.md +29 -0
- package/skills/sodax-dapp-kit/integration/knowledge/features/auxiliary-services.md +169 -0
- package/skills/sodax-dapp-kit/integration/knowledge/features/bitcoin.md +87 -0
- package/skills/sodax-dapp-kit/integration/knowledge/features/bridge.md +91 -0
- package/skills/sodax-dapp-kit/integration/knowledge/features/dex.md +152 -0
- package/skills/sodax-dapp-kit/integration/knowledge/features/migration.md +118 -0
- package/skills/sodax-dapp-kit/integration/knowledge/features/money-market.md +144 -0
- package/skills/sodax-dapp-kit/integration/knowledge/features/staking.md +123 -0
- package/skills/sodax-dapp-kit/integration/knowledge/features/swap.md +101 -0
- package/skills/sodax-dapp-kit/integration/knowledge/quickstart.md +188 -0
- package/skills/sodax-dapp-kit/integration/knowledge/recipes/README.md +136 -0
- package/skills/sodax-dapp-kit/integration/knowledge/recipes/backend-queries.md +157 -0
- package/skills/sodax-dapp-kit/integration/knowledge/recipes/bitcoin.md +193 -0
- package/skills/sodax-dapp-kit/integration/knowledge/recipes/bridge.md +174 -0
- package/skills/sodax-dapp-kit/integration/knowledge/recipes/dex.md +204 -0
- package/skills/sodax-dapp-kit/integration/knowledge/recipes/invalidations.md +115 -0
- package/skills/sodax-dapp-kit/integration/knowledge/recipes/migration.md +212 -0
- package/skills/sodax-dapp-kit/integration/knowledge/recipes/money-market.md +207 -0
- package/skills/sodax-dapp-kit/integration/knowledge/recipes/mutation-error-handling.md +118 -0
- package/skills/sodax-dapp-kit/integration/knowledge/recipes/observability.md +93 -0
- package/skills/sodax-dapp-kit/integration/knowledge/recipes/setup.md +168 -0
- package/skills/sodax-dapp-kit/integration/knowledge/recipes/staking.md +202 -0
- package/skills/sodax-dapp-kit/integration/knowledge/recipes/swap.md +272 -0
- package/skills/sodax-dapp-kit/integration/knowledge/recipes/wallet-connectivity.md +128 -0
- package/skills/sodax-dapp-kit/integration/knowledge/reference/README.md +12 -0
- package/skills/sodax-dapp-kit/integration/knowledge/reference/glossary.md +190 -0
- package/skills/sodax-dapp-kit/integration/knowledge/reference/hooks-index.md +190 -0
- package/skills/sodax-dapp-kit/integration/knowledge/reference/public-api.md +110 -0
- package/skills/sodax-dapp-kit/integration/knowledge/reference/querykey-conventions.md +179 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/README.md +60 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/ai-rules.md +81 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/breaking-changes/hook-signatures.md +233 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/breaking-changes/querykey-conventions.md +108 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/breaking-changes/result-handling.md +211 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/breaking-changes/sdk-leakage.md +167 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/checklist.md +89 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/features/README.md +34 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/features/auxiliary-services.md +114 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/features/bitcoin.md +88 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/features/bridge.md +160 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/features/dex.md +101 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/features/migration.md +120 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/features/money-market.md +139 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/features/staking.md +109 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/features/swap.md +133 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/recipes.md +185 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/reference/README.md +15 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/reference/deleted-hooks.md +110 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/reference/error-shape-crosswalk.md +144 -0
- package/skills/sodax-dapp-kit/migration-v1-to-v2/knowledge/reference/renamed-hooks.md +68 -0
- package/skills/sodax-sdk/SKILL.md +140 -0
- package/skills/sodax-sdk/backend-api/SKILL.md +52 -0
- package/skills/sodax-sdk/bridge/SKILL.md +49 -0
- package/skills/sodax-sdk/dex/SKILL.md +50 -0
- package/skills/sodax-sdk/integration/knowledge/README.md +43 -0
- package/skills/sodax-sdk/integration/knowledge/ai-rules.md +75 -0
- package/skills/sodax-sdk/integration/knowledge/architecture.md +517 -0
- package/skills/sodax-sdk/integration/knowledge/chain-specifics.md +189 -0
- package/skills/sodax-sdk/integration/knowledge/features/README.md +21 -0
- package/skills/sodax-sdk/integration/knowledge/features/backend-api.md +81 -0
- package/skills/sodax-sdk/integration/knowledge/features/bridge.md +172 -0
- package/skills/sodax-sdk/integration/knowledge/features/dex.md +182 -0
- package/skills/sodax-sdk/integration/knowledge/features/migration.md +181 -0
- package/skills/sodax-sdk/integration/knowledge/features/money-market.md +198 -0
- package/skills/sodax-sdk/integration/knowledge/features/partner.md +63 -0
- package/skills/sodax-sdk/integration/knowledge/features/recovery.md +50 -0
- package/skills/sodax-sdk/integration/knowledge/features/staking.md +171 -0
- package/skills/sodax-sdk/integration/knowledge/features/swap.md +273 -0
- package/skills/sodax-sdk/integration/knowledge/quickstart.md +213 -0
- package/skills/sodax-sdk/integration/knowledge/recipes/README.md +21 -0
- package/skills/sodax-sdk/integration/knowledge/recipes/backend-server-init.md +69 -0
- package/skills/sodax-sdk/integration/knowledge/recipes/chain-key-narrowing.md +65 -0
- package/skills/sodax-sdk/integration/knowledge/recipes/gas-estimation.md +33 -0
- package/skills/sodax-sdk/integration/knowledge/recipes/initialize-sodax.md +78 -0
- package/skills/sodax-sdk/integration/knowledge/recipes/raw-tx-flow.md +71 -0
- package/skills/sodax-sdk/integration/knowledge/recipes/result-and-errors.md +104 -0
- package/skills/sodax-sdk/integration/knowledge/recipes/signed-tx-flow.md +46 -0
- package/skills/sodax-sdk/integration/knowledge/recipes/testing.md +101 -0
- package/skills/sodax-sdk/integration/knowledge/reference/README.md +18 -0
- package/skills/sodax-sdk/integration/knowledge/reference/chain-keys.md +67 -0
- package/skills/sodax-sdk/integration/knowledge/reference/error-codes.md +165 -0
- package/skills/sodax-sdk/integration/knowledge/reference/glossary.md +32 -0
- package/skills/sodax-sdk/integration/knowledge/reference/public-api.md +138 -0
- package/skills/sodax-sdk/integration/knowledge/reference/wallet-providers.md +62 -0
- package/skills/sodax-sdk/migration/SKILL.md +65 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/README.md +58 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/ai-rules.md +76 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/breaking-changes/architecture.md +344 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/breaking-changes/result-and-errors.md +363 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/breaking-changes/type-system.md +341 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/checklist.md +67 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/README.md +37 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/backend-api.md +92 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/bridge.md +128 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/dex.md +143 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/migration.md +151 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/money-market.md +214 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/partner.md +59 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/recovery.md +35 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/staking.md +143 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/features/swap.md +198 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/recipes.md +350 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/reference/README.md +18 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/reference/deleted-exports.md +127 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/reference/error-code-crosswalk.md +104 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/reference/return-shapes.md +49 -0
- package/skills/sodax-sdk/migration-v1-to-v2/knowledge/reference/sodax-config.md +145 -0
- package/skills/sodax-sdk/money-market/SKILL.md +52 -0
- package/skills/sodax-sdk/partner/SKILL.md +51 -0
- package/skills/sodax-sdk/recovery/SKILL.md +49 -0
- package/skills/sodax-sdk/staking/SKILL.md +49 -0
- package/skills/sodax-sdk/swap/SKILL.md +67 -0
- package/skills/sodax-wallet-sdk-core/SKILL.md +114 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/README.md +108 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/ai-rules.md +141 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/architecture.md +212 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/features/README.md +22 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/features/bitcoin.md +103 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/features/evm.md +102 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/features/icon.md +88 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/features/injective.md +92 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/features/near.md +92 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/features/solana.md +104 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/features/stacks.md +91 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/features/stellar.md +95 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/features/sui.md +96 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/quickstart.md +259 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/recipes/README.md +15 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/recipes/bridge-to-sdk.md +145 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/recipes/defaults-and-overrides.md +159 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/recipes/library-exports.md +129 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/recipes/setup-browser-extension.md +137 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/recipes/setup-private-key.md +115 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/recipes/sign-and-broadcast.md +201 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/recipes/testing.md +163 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/reference/README.md +13 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/reference/chain-support.md +65 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/reference/glossary.md +28 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/reference/interfaces.md +131 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/reference/provider-classes.md +54 -0
- package/skills/sodax-wallet-sdk-core/integration/knowledge/reference/public-api.md +128 -0
- package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/README.md +84 -0
- package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/ai-rules.md +139 -0
- package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/breaking-changes/README.md +14 -0
- package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/breaking-changes/base-wallet-provider.md +52 -0
- package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/breaking-changes/defaults-config.md +57 -0
- package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/breaking-changes/folder-layout.md +99 -0
- package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/breaking-changes/library-exports.md +58 -0
- package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/checklist.md +62 -0
- package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/recipes/README.md +12 -0
- package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/recipes/adopt-defaults.md +84 -0
- package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/recipes/adopt-library-exports.md +99 -0
- package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/reference/README.md +12 -0
- package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/reference/added-fields.md +71 -0
- package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/reference/deleted-exports.md +35 -0
- package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/reference/renamed-symbols.md +31 -0
- package/skills/sodax-wallet-sdk-core/migration-v1-to-v2/knowledge/reference/return-shapes.md +23 -0
- package/skills/sodax-wallet-sdk-react/SKILL.md +154 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/README.md +103 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/ai-rules.md +136 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/architecture.md +185 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/examples/01-minimal-evm.tsx +75 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/examples/02-multi-chain-modal.tsx +169 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/examples/03-nextjs-app-router.tsx +99 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/examples/04-walletconnect-setup.tsx +89 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/examples/README.md +29 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/batch-operations.md +224 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/bridge-to-sdk.md +165 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/chain-detection.md +259 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/connect-button.md +159 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/multi-chain-modal.md +203 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/setup.md +163 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/sign-message.md +138 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/sub-path-imports.md +97 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/switch-chain.md +144 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/recipes/walletconnect-setup.md +139 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/reference/api-surface.md +176 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/reference/chain-support.md +79 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/reference/connectors.md +75 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/reference/hooks.md +212 -0
- package/skills/sodax-wallet-sdk-react/integration/knowledge/reference/wallet-brands.md +107 -0
- package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/README.md +49 -0
- package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/ai-rules.md +144 -0
- package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/breaking-changes.md +310 -0
- package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/checklist.md +159 -0
- package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/recipes/connect-button.md +170 -0
- package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/recipes/multi-chain-modal.md +245 -0
- package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/recipes/ssr-setup.md +165 -0
- package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/recipes/walletconnect-migration.md +170 -0
- package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/reference/components.md +75 -0
- package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/reference/config.md +339 -0
- package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/reference/hooks.md +336 -0
- package/skills/sodax-wallet-sdk-react/migration-v1-to-v2/knowledge/reference/imports.md +158 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Initialize Sodax
|
|
2
|
+
|
|
3
|
+
The minimal init — packaged defaults, no config override:
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { Sodax } from '@sodax/sdk';
|
|
7
|
+
|
|
8
|
+
const sodax = new Sodax();
|
|
9
|
+
await sodax.config.initialize(); // load fresh config from backend; falls back to packaged defaults
|
|
10
|
+
|
|
11
|
+
// All feature services are wired and ready:
|
|
12
|
+
const result = sodax.config.isValidSpokeChainKey(ChainKeys.ARBITRUM_MAINNET); // returns boolean (sync)
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### With config override
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { Sodax, ChainKeys, type SodaxConfig, type DeepPartial } from '@sodax/sdk';
|
|
19
|
+
|
|
20
|
+
const config: DeepPartial<SodaxConfig> = {
|
|
21
|
+
// Per-chain overrides — merged with packaged defaults at the field level.
|
|
22
|
+
chains: {
|
|
23
|
+
[ChainKeys.SONIC_MAINNET]: { rpcUrl: process.env.SONIC_RPC_URL },
|
|
24
|
+
[ChainKeys.ARBITRUM_MAINNET]: { rpcUrl: process.env.ARBITRUM_RPC_URL },
|
|
25
|
+
},
|
|
26
|
+
// Backend API override (default: https://api.sodax.com/v1/be).
|
|
27
|
+
api: {
|
|
28
|
+
baseURL: 'https://my-sandbox-backend.example.com',
|
|
29
|
+
},
|
|
30
|
+
// Solver endpoints (default: https://api.sodax.com/v1/intent + production contracts).
|
|
31
|
+
solver: {
|
|
32
|
+
solverApiEndpoint: 'https://my-solver.example.com',
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const sodax = new Sodax(config);
|
|
37
|
+
await sodax.config.initialize();
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Lazy initialization
|
|
41
|
+
|
|
42
|
+
`config.initialize()` is idempotent — calling it twice is a no-op. The first call fetches; subsequent calls return cached data. Treat it as "make sure config is loaded before any feature method".
|
|
43
|
+
|
|
44
|
+
### Pitfall
|
|
45
|
+
|
|
46
|
+
`initialize()` is the only initialization step. Don't `await` it inside every feature call — call it once at app startup. If you skip it entirely, feature services fall back to packaged defaults, which may be stale relative to the latest backend config (new tokens, new chains, fee parameter changes).
|
|
47
|
+
|
|
48
|
+
## Module-scope reads (no Sodax instance needed)
|
|
49
|
+
|
|
50
|
+
Some code runs at **module-load time** — constants files, utility modules, framework-provider configs — before any `Sodax` instance exists. For those, import the packaged-default constants directly from `@sodax/sdk` (re-exported from `@sodax/types`):
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
import { sodaxConfig, hubConfig } from '@sodax/sdk';
|
|
54
|
+
|
|
55
|
+
// Hub address constants
|
|
56
|
+
export const HUB_WALLET = hubConfig.addresses.hubWallet;
|
|
57
|
+
export const STAKING_ROUTER = hubConfig.addresses.stakingRouter;
|
|
58
|
+
|
|
59
|
+
// Full default config (every SodaxConfig field with packaged defaults)
|
|
60
|
+
export const DEFAULT_SOLVER_ENDPOINT = sodaxConfig.solver.solverApiEndpoint;
|
|
61
|
+
export const SUPPORTED_TOKENS_PER_CHAIN = sodaxConfig.swaps.supportedTokens;
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
| Need | Module-scope import (defaults only) | Instance-scope read (with overrides) |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| Hub contract addresses (assetManager, hubWallet, stakingRouter, etc.) | `hubConfig.addresses.*` | `sodax.config.getHubChainConfig().addresses.*` |
|
|
67
|
+
| Full default SodaxConfig (read-only snapshot) | `sodaxConfig.*` (e.g. `sodaxConfig.hub`, `sodaxConfig.moneyMarket`) | `sodax.config.sodaxConfig` |
|
|
68
|
+
| Per-chain spoke config (rpcUrl, nativeToken, addresses, supportedTokens, polling) | `spokeChainConfig[ChainKeys.X_MAINNET]` (from `@sodax/types` / `@sodax/sdk`) | `sodax.config.spokeChainConfig[ChainKeys.X_MAINNET]` *or* `sodax.config.getChainConfig(ChainKeys.X_MAINNET)` |
|
|
69
|
+
| Money market reserve assets | `sodaxConfig.moneyMarket.supportedReserveAssets` | `sodax.config.getMoneyMarketReserveAssets()` |
|
|
70
|
+
|
|
71
|
+
> **Static vs dynamic — and the override-gap consequence.** `sodaxConfig` / `hubConfig` / `spokeChainConfig` are **packaged-default snapshots** frozen at SDK release time. They are safe at module scope but: (a) won't reflect backend-driven config updates loaded by `sodax.config.initialize()`, and (b) **won't reflect overrides passed to `new Sodax(config)`** — those merge into `sodax.config` (the `ConfigService`) but never mutate the static imports. So once a `Sodax` instance exists, prefer the instance-scope readers in the right column above — particularly `sodax.config.spokeChainConfig` over the same-named static import — or you will silently fall back to the packaged defaults for any chain you customized.
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
## Cross-references
|
|
75
|
+
|
|
76
|
+
- [`README.md`](README.md) — recipe index.
|
|
77
|
+
- [`../architecture.md`](../architecture.md) — concepts behind these patterns.
|
|
78
|
+
- [`../reference/`](../reference/) — chain keys, error codes, public API surface.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Raw-tx flow
|
|
2
|
+
|
|
3
|
+
`raw: true`. The SDK builds the unsigned payload; you sign it elsewhere (gnosis safe, hardware wallet, multi-sig, etc.).
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
const result = await sodax.swaps.createIntent({
|
|
7
|
+
params: { /* same as signed flow */ },
|
|
8
|
+
raw: true,
|
|
9
|
+
// walletProvider is FORBIDDEN — TypeScript rejects it.
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
if (!result.ok) return;
|
|
13
|
+
const { tx, intent, relayData } = result.value;
|
|
14
|
+
// tx is now a chain-specific raw-tx payload:
|
|
15
|
+
// - EVM: EvmRawTransaction { to, data, value, chainId }
|
|
16
|
+
// - Solana: SolanaRawTransaction
|
|
17
|
+
// - Stellar: StellarRawTransaction
|
|
18
|
+
// - …
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Submit the raw tx via your own signing infrastructure. Once you have the spoke tx hash, you'll typically need to manually call the relay to complete the cross-chain flow:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { relayTxAndWaitPacket, type RelayExtraData } from '@sodax/sdk';
|
|
25
|
+
|
|
26
|
+
// After your custom signer broadcasts and you have the spoke tx hash:
|
|
27
|
+
const spokeTxHash = await mySigningInfra.signAndBroadcast(tx);
|
|
28
|
+
|
|
29
|
+
// `relayTxAndWaitPacket` is a top-level function (not a class). Pass your
|
|
30
|
+
// relayer endpoint (same one you'd configure on the `Sodax` instance) and
|
|
31
|
+
// the relay payload returned by `createIntent`.
|
|
32
|
+
const relayResult = await relayTxAndWaitPacket({
|
|
33
|
+
relayerApiEndpoint,
|
|
34
|
+
srcChainKey: params.srcChainKey,
|
|
35
|
+
dstChainKey: params.dstChainKey,
|
|
36
|
+
txHash: spokeTxHash,
|
|
37
|
+
payload: relayData.payload,
|
|
38
|
+
timeout: 60_000,
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
This pattern is rare. Prefer signed flow unless you have a specific reason to defer signing.
|
|
43
|
+
|
|
44
|
+
### Type narrowing
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
// Discriminate raw return shapes by chain family at runtime:
|
|
48
|
+
if (getChainType(srcChainKey) === 'EVM') {
|
|
49
|
+
const evmTx = result.value.tx as EvmRawTransaction;
|
|
50
|
+
// …
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Or use the chain-key generic to narrow at the type level (most useful when `srcChainKey` is a literal):
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
const result = await sodax.swaps.createIntent({
|
|
58
|
+
params: { ...params, srcChainKey: ChainKeys.ETHEREUM_MAINNET as const },
|
|
59
|
+
raw: true,
|
|
60
|
+
});
|
|
61
|
+
// result.value.tx is statically narrowed to EvmRawTransaction
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
## Cross-references
|
|
68
|
+
|
|
69
|
+
- [`README.md`](README.md) — recipe index.
|
|
70
|
+
- [`../architecture.md`](../architecture.md) — concepts behind these patterns.
|
|
71
|
+
- [`../reference/`](../reference/) — chain keys, error codes, public API surface.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Result handling and error discrimination
|
|
2
|
+
|
|
3
|
+
Every async public method on every feature service returns `Promise<Result<T, SodaxError<C>>>`.
|
|
4
|
+
|
|
5
|
+
### Branching pattern
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { isSodaxError } from '@sodax/sdk';
|
|
9
|
+
|
|
10
|
+
const result = await sodax.swaps.createIntent({ params, raw: false, walletProvider });
|
|
11
|
+
|
|
12
|
+
if (!result.ok) {
|
|
13
|
+
// Always isSodaxError-narrow before reading .feature / .code
|
|
14
|
+
if (isSodaxError(result.error)) {
|
|
15
|
+
if (result.error.code === 'RELAY_TIMEOUT') {
|
|
16
|
+
// retry strategy
|
|
17
|
+
} else if (result.error.feature === 'swap' && result.error.code === 'INTENT_CREATION_FAILED') {
|
|
18
|
+
// input-error UX
|
|
19
|
+
} else if (result.error.code === 'EXTERNAL_API_ERROR' && result.error.context?.api === 'solver') {
|
|
20
|
+
// solver-side problem; surface error.context.solverDetail to the user
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const { tx, intent, relayData } = result.value;
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Switch-style with narrow code unions
|
|
30
|
+
|
|
31
|
+
When you know the method, the narrow code union from its declaration enables an exhaustive switch:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
type CreateSupplyIntentErrorCode = 'VALIDATION_FAILED' | 'INTENT_CREATION_FAILED' | 'UNKNOWN';
|
|
35
|
+
|
|
36
|
+
const result = await sodax.moneyMarket.createSupplyIntent({ params, raw: true });
|
|
37
|
+
if (!result.ok) {
|
|
38
|
+
switch (result.error.code as CreateSupplyIntentErrorCode) {
|
|
39
|
+
case 'VALIDATION_FAILED': return setError('Invalid input');
|
|
40
|
+
case 'INTENT_CREATION_FAILED': return setError('Could not build supply');
|
|
41
|
+
case 'UNKNOWN': return setError('Unexpected error');
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Per-feature guard factory
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { isFeatureError } from '@sodax/sdk';
|
|
50
|
+
|
|
51
|
+
const isSwapError = isFeatureError('swap');
|
|
52
|
+
const isMmError = isFeatureError('moneyMarket');
|
|
53
|
+
|
|
54
|
+
if (!result.ok) {
|
|
55
|
+
if (isSwapError(result.error)) /* … */;
|
|
56
|
+
else if (isMmError(result.error)) /* … */;
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Sub-Result propagation
|
|
61
|
+
|
|
62
|
+
For wrapper methods you write yourself:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
async function myWorkflow(): Promise<Result<MyOutput, SodaxError>> {
|
|
66
|
+
const sub = await sodax.swaps.createIntent({ params, raw: false, walletProvider });
|
|
67
|
+
if (!sub.ok) return sub; // forward as-is
|
|
68
|
+
|
|
69
|
+
const { tx, intent } = sub.value;
|
|
70
|
+
return { ok: true, value: { tx, intent, ts: Date.now() } };
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Logging
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { isSodaxError } from '@sodax/sdk';
|
|
78
|
+
|
|
79
|
+
if (!result.ok) {
|
|
80
|
+
if (isSodaxError(result.error)) {
|
|
81
|
+
Sentry.captureException(result.error, {
|
|
82
|
+
tags: {
|
|
83
|
+
feature: result.error.feature,
|
|
84
|
+
code: result.error.code,
|
|
85
|
+
action: result.error.context?.action ?? null,
|
|
86
|
+
relayCode: result.error.context?.relayCode ?? null,
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
} else {
|
|
90
|
+
Sentry.captureException(result.error);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`SodaxError.toJSON()` is invoked automatically by `JSON.stringify(error)` — Pino, Datadog, and Winston pick it up without configuration.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
## Cross-references
|
|
101
|
+
|
|
102
|
+
- [`README.md`](README.md) — recipe index.
|
|
103
|
+
- [`../architecture.md`](../architecture.md) — concepts behind these patterns.
|
|
104
|
+
- [`../reference/`](../reference/) — chain keys, error codes, public API surface.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Signed-tx flow
|
|
2
|
+
|
|
3
|
+
`raw: false` + a chain-narrowed `walletProvider`. The SDK signs and broadcasts; returns a tx hash (or tx-pair for cross-chain methods).
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
const result = await sodax.swaps.createIntent({
|
|
7
|
+
params: {
|
|
8
|
+
srcChainKey: ChainKeys.ARBITRUM_MAINNET,
|
|
9
|
+
dstChainKey: ChainKeys.STELLAR_MAINNET,
|
|
10
|
+
srcAddress: '0x…',
|
|
11
|
+
dstAddress: 'G…',
|
|
12
|
+
inputToken, // XToken
|
|
13
|
+
outputToken, // XToken
|
|
14
|
+
inputAmount: 1_000_000n,
|
|
15
|
+
minOutputAmount: 998_000n,
|
|
16
|
+
deadline: BigInt(Math.floor(Date.now() / 1000) + 300),
|
|
17
|
+
allowPartialFill: false,
|
|
18
|
+
solver: '0x0000000000000000000000000000000000000000',
|
|
19
|
+
data: '0x',
|
|
20
|
+
},
|
|
21
|
+
raw: false,
|
|
22
|
+
walletProvider: evmWallet, // IEvmWalletProvider — narrowed by srcChainKey
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
if (!result.ok) return;
|
|
26
|
+
const { tx, intent, relayData } = result.value;
|
|
27
|
+
// tx: the spoke tx hash (string for EVM, base58 for Solana, …)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
For cross-chain mutations (`bridge.bridge`, `staking.stake`, `moneyMarket.supply/borrow/withdraw/repay`, `dex.deposit/withdraw/supplyLiquidity/…`, `migration.migratebnUSD/…`) the success value is `TxHashPair = { srcChainTxHash, dstChainTxHash }` — the spoke transaction hash on the source chain plus the relayed hub transaction hash:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
const result = await sodax.bridge.bridge({ params, raw: false, walletProvider });
|
|
34
|
+
if (!result.ok) return;
|
|
35
|
+
const { srcChainTxHash, dstChainTxHash } = result.value;
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The same shape is used by every cross-chain mutation in v2 — there is no array-form variant. When the user is already on the hub, both fields hold the same hash.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Cross-references
|
|
43
|
+
|
|
44
|
+
- [`README.md`](README.md) — recipe index.
|
|
45
|
+
- [`../architecture.md`](../architecture.md) — concepts behind these patterns.
|
|
46
|
+
- [`../reference/`](../reference/) — chain keys, error codes, public API surface.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Testing (mocks and stubs)
|
|
2
|
+
|
|
3
|
+
### Mock the entire `Sodax` instance
|
|
4
|
+
|
|
5
|
+
For unit tests where you want to verify your code calls the SDK correctly without hitting network:
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import type { Sodax } from '@sodax/sdk';
|
|
9
|
+
import { vi } from 'vitest';
|
|
10
|
+
|
|
11
|
+
const mockSodax = {
|
|
12
|
+
swaps: {
|
|
13
|
+
createIntent: vi.fn(),
|
|
14
|
+
swap: vi.fn(),
|
|
15
|
+
},
|
|
16
|
+
config: {
|
|
17
|
+
initialize: vi.fn().mockResolvedValue(undefined),
|
|
18
|
+
isValidSpokeChainKey: vi.fn().mockReturnValue(true),
|
|
19
|
+
},
|
|
20
|
+
} as unknown as Sodax;
|
|
21
|
+
|
|
22
|
+
mockSodax.swaps.createIntent.mockResolvedValue({
|
|
23
|
+
ok: true,
|
|
24
|
+
value: {
|
|
25
|
+
tx: '0xabc' as `0x${string}`,
|
|
26
|
+
intent: { /* … */ },
|
|
27
|
+
relayData: { payload: '0x…' },
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Use mockSodax in your code under test
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The cast `as unknown as Sodax` is the **only** place where `as unknown as` is acceptable per the project conventions — test mocks intentionally defeat types.
|
|
35
|
+
|
|
36
|
+
### Stub the relay layer for E2E tests
|
|
37
|
+
|
|
38
|
+
When you want real spoke txs but stubbed relay coordination, mock at the **feature service** boundary — `relayTxAndWaitPacket` is consumed by feature-service implementations internally, and is not exposed on the `Sodax` instance.
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { Sodax } from '@sodax/sdk';
|
|
42
|
+
import { vi } from 'vitest';
|
|
43
|
+
|
|
44
|
+
const sodax = new Sodax({ /* … */ });
|
|
45
|
+
|
|
46
|
+
// Stub the full feature method (it wraps relay coordination internally):
|
|
47
|
+
vi.spyOn(sodax.swaps, 'swap').mockResolvedValue({
|
|
48
|
+
ok: true,
|
|
49
|
+
value: {
|
|
50
|
+
solverExecutionResponse: { /* … */ },
|
|
51
|
+
intent: { /* … */ },
|
|
52
|
+
intentDeliveryInfo: { /* … */ },
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Or stub just the relay portion of an end-to-end flow by mocking
|
|
57
|
+
// `sodax.swaps.postExecution` after `createIntent` returns.
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Result-style assertions
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
const result = await sodax.swaps.createIntent({ params, raw: false, walletProvider });
|
|
64
|
+
expect(result.ok).toBe(true);
|
|
65
|
+
if (result.ok) {
|
|
66
|
+
expect(result.value.tx).toMatch(/^0x[0-9a-f]{64}$/);
|
|
67
|
+
}
|
|
68
|
+
// or for failures:
|
|
69
|
+
expect(result.ok).toBe(false);
|
|
70
|
+
if (!result.ok) {
|
|
71
|
+
expect(result.error).toBeInstanceOf(Error);
|
|
72
|
+
expect(result.error.code).toBe('VALIDATION_FAILED');
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Custom `IConfigApi` for sandbox
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { Sodax, type IConfigApi } from '@sodax/sdk';
|
|
80
|
+
|
|
81
|
+
const sandboxApi: IConfigApi = {
|
|
82
|
+
async getChains() { return { ok: true, value: [/* fixture */] }; },
|
|
83
|
+
async getSwapTokens() { return { ok: true, value: { /* … */ } }; },
|
|
84
|
+
async getSwapTokensByChainId(chainKey) { return { ok: true, value: [/* … */] }; },
|
|
85
|
+
async getMoneyMarketTokens() { return { ok: true, value: { /* … */ } }; },
|
|
86
|
+
async getMoneyMarketTokensByChainId(chainKey) { return { ok: true, value: [/* … */] }; },
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const sodax = new Sodax({
|
|
90
|
+
backendApi: { url: 'unused', api: sandboxApi },
|
|
91
|
+
});
|
|
92
|
+
await sodax.config.initialize();
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Cross-references
|
|
98
|
+
|
|
99
|
+
- [`README.md`](README.md) — recipe index.
|
|
100
|
+
- [`../architecture.md`](../architecture.md) — concepts behind these patterns.
|
|
101
|
+
- [`../reference/`](../reference/) — chain keys, error codes, public API surface.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Reference — `@sodax/sdk` v2
|
|
2
|
+
|
|
3
|
+
Lookup tables and inventories. Each file is focused on one domain — token-cheap retrieval.
|
|
4
|
+
|
|
5
|
+
| File | Contents |
|
|
6
|
+
|---|---|
|
|
7
|
+
| [`chain-keys.md`](chain-keys.md) | All 20 `ChainKeys.*` values × chain family × address-type mapping. Chain-family helper functions. Type aliases (`ChainKey`, `SpokeChainKey`, `EvmChainKey`, `HubChainKey`). |
|
|
8
|
+
| [`wallet-providers.md`](wallet-providers.md) | `I*WalletProvider` interfaces per chain family. `chainType` discriminant. `GetWalletProviderType<K>`. `IWalletProvider` broad union. Implementation source (consumer's own, or `@sodax/wallet-sdk-core` separate package). |
|
|
9
|
+
| [`error-codes.md`](error-codes.md) | The 13 unified `SodaxErrorCode` values + meanings + retry guidance + common context fields. The 8 `SodaxFeature` tags. The `SodaxPhase` orchestration tags. Per-method narrow code unions for every public method on every service. |
|
|
10
|
+
| [`public-api.md`](public-api.md) | What `@sodax/sdk` barrel exports. Import-rule contract (root-only, no deep imports, types re-exported from `@sodax/types`). |
|
|
11
|
+
| [`glossary.md`](glossary.md) | Domain terms (hub, spoke, intent, relay, vault, hub-wallet abstraction, etc.) used throughout the docs. |
|
|
12
|
+
|
|
13
|
+
## Cross-references
|
|
14
|
+
|
|
15
|
+
- v2 architectural concepts (the prose behind these tables): [`../architecture.md`](../architecture.md).
|
|
16
|
+
- Recipes that use these lookups: [`../recipes/`](../recipes/).
|
|
17
|
+
- DO / DO NOT / workflow: [`../ai-rules.md`](../ai-rules.md).
|
|
18
|
+
- v1 → v2 migration: [`sodax-sdk` (migration mode)](../../../migration-v1-to-v2/knowledge/).
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Chain keys
|
|
2
|
+
|
|
3
|
+
20 supported chains. The `ChainKey` type is the union of every `ChainKeys.*` value. **`SpokeChainKey` is the same union — it includes Sonic.** The "spoke" naming refers to how feature services type their `srcChainKey` parameter (they accept the hub too — bridge / swap / staking etc. all run from Sonic as source via the hub-wallet abstraction). When you specifically need "EVM chains excluding the hub" use `EVM_SPOKE_ONLY_CHAIN_KEYS` / `isEvmSpokeOnlyChainKeyType`.
|
|
4
|
+
|
|
5
|
+
| `ChainKeys.*` | String value | Family | Hub vs spoke | Address type |
|
|
6
|
+
|---|---|---|---|---|
|
|
7
|
+
| `SONIC_MAINNET` | `'sonic'` | EVM | **Hub** | `0x${string}` |
|
|
8
|
+
| `ETHEREUM_MAINNET` | `'ethereum'` | EVM | spoke | `0x${string}` |
|
|
9
|
+
| `ARBITRUM_MAINNET` | `'0xa4b1.arbitrum'` | EVM | spoke | `0x${string}` |
|
|
10
|
+
| `BASE_MAINNET` | `'0x2105.base'` | EVM | spoke | `0x${string}` |
|
|
11
|
+
| `BSC_MAINNET` | `'0x38.bsc'` | EVM | spoke | `0x${string}` |
|
|
12
|
+
| `OPTIMISM_MAINNET` | `'0xa.optimism'` | EVM | spoke | `0x${string}` |
|
|
13
|
+
| `POLYGON_MAINNET` | `'0x89.polygon'` | EVM | spoke | `0x${string}` |
|
|
14
|
+
| `AVALANCHE_MAINNET` | `'0xa86a.avax'` | EVM | spoke | `0x${string}` |
|
|
15
|
+
| `HYPEREVM_MAINNET` | `'hyper'` | EVM | spoke | `0x${string}` |
|
|
16
|
+
| `LIGHTLINK_MAINNET` | `'lightlink'` | EVM | spoke | `0x${string}` |
|
|
17
|
+
| `REDBELLY_MAINNET` | `'redbelly'` | EVM | spoke | `0x${string}` |
|
|
18
|
+
| `KAIA_MAINNET` | `'0x2019.kaia'` | EVM | spoke | `0x${string}` |
|
|
19
|
+
| `SOLANA_MAINNET` | `'solana'` | SOLANA | spoke | base58 PublicKey string |
|
|
20
|
+
| `SUI_MAINNET` | `'sui'` | SUI | spoke | `0x${string}` (32-byte) |
|
|
21
|
+
| `STELLAR_MAINNET` | `'stellar'` | STELLAR | spoke | `G…` |
|
|
22
|
+
| `ICON_MAINNET` | `'0x1.icon'` | ICON | spoke | `hx…` / `cx…` |
|
|
23
|
+
| `INJECTIVE_MAINNET` | `'injective-1'` | INJECTIVE | spoke | `inj1…` |
|
|
24
|
+
| `NEAR_MAINNET` | `'near'` | NEAR | spoke | `<account>.near` / `<hex>` |
|
|
25
|
+
| `STACKS_MAINNET` | `'stacks'` | STACKS | spoke | `SP…` / `ST…` |
|
|
26
|
+
| `BITCOIN_MAINNET` | `'bitcoin'` | BITCOIN | spoke | `bc1…` / `1…` / `3…` |
|
|
27
|
+
|
|
28
|
+
### Notes
|
|
29
|
+
|
|
30
|
+
- `ChainKeys.ICON_MAINNET` is the **string** `'0x1.icon'`, not the legacy numeric chain id. `Number(chainKey)` returns `NaN` for ICON.
|
|
31
|
+
- `SONIC_MAINNET` is special-cased — it's `'sonic'` (a simple string) and is the hub chain. `getChainType(ChainKeys.SONIC_MAINNET)` returns `'EVM'` (since Sonic is EVM-compatible) and `'SONIC'` is also a valid family in some contexts.
|
|
32
|
+
- Relay chain IDs (used internally for cross-chain coordination) are different from `ChainKey` strings. Convert via `sodax.config.getSpokeChainKeyFromIntentRelayChainId(BigInt(relayId))`.
|
|
33
|
+
|
|
34
|
+
### Type aliases
|
|
35
|
+
|
|
36
|
+
| Type | What it is |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `ChainKey` | Union of all `ChainKeys.*` values (20 chains). |
|
|
39
|
+
| `SpokeChainKey` | `ChainKey` minus `'sonic'` (19 spoke chains). |
|
|
40
|
+
| `EvmChainKey` | Subset of `ChainKey` for the 12 EVM chains. |
|
|
41
|
+
| `HubChainKey` | The literal `'sonic'`. |
|
|
42
|
+
|
|
43
|
+
### Chain-family helpers
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import {
|
|
47
|
+
getChainType, // (chainKey) => 'EVM' | 'BITCOIN' | ...
|
|
48
|
+
isEvmChainKeyType,
|
|
49
|
+
isSolanaChainKeyType,
|
|
50
|
+
isStellarChainKeyType,
|
|
51
|
+
isSuiChainKeyType,
|
|
52
|
+
isIconChainKeyType,
|
|
53
|
+
isInjectiveChainKeyType,
|
|
54
|
+
isStacksChainKeyType,
|
|
55
|
+
isNearChainKeyType,
|
|
56
|
+
isBitcoinChainKeyType,
|
|
57
|
+
isHubChainKeyType,
|
|
58
|
+
} from '@sodax/sdk';
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
## Cross-references
|
|
65
|
+
|
|
66
|
+
- [`README.md`](README.md) — reference index.
|
|
67
|
+
- [`../architecture.md`](../architecture.md) — concepts behind these tables.
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Error codes
|
|
2
|
+
|
|
3
|
+
All 13 codes the SDK can emit. Each error is `SodaxError<C>` where `C` is one of these. The producing feature is on `error.feature`.
|
|
4
|
+
|
|
5
|
+
| Code | Meaning | Common `error.context` fields | Retry advice |
|
|
6
|
+
|---|---|---|---|
|
|
7
|
+
| `VALIDATION_FAILED` | Pre-flight invariant tripped (input shape, unsupported chain, etc.). | `field`, `reason`, `phase: 'validate'` | No — fix the input. |
|
|
8
|
+
| `INTENT_CREATION_FAILED` | Building the intent / payload failed. | `phase: 'intentCreation'`, `action` | Sometimes — depends on root cause (`error.cause`). |
|
|
9
|
+
| `EXECUTION_FAILED` | Orchestrator-level catch-all (multi-step op didn't complete). | `action`, `phase: 'execution'` or `'postExecution'` | Sometimes — inspect cause. |
|
|
10
|
+
| `TX_VERIFICATION_FAILED` | Spoke `verifyTxHash` returned false / threw. | `phase: 'verify'`, `srcChainKey` | Sometimes — RPC / indexer issue is transient. |
|
|
11
|
+
| `TX_SUBMIT_FAILED` | Spoke tx landed; relay POST submit failed. | `phase: 'submit'`, `relayCode: 'SUBMIT_TX_FAILED'` | Yes — relay submit is retryable; backoff and re-run with the same payload. |
|
|
12
|
+
| `RELAY_TIMEOUT` | Destination packet didn't reach `executed` within timeout. | `phase: 'relay'`, `srcChainKey`, `dstChainKey`, `relayCode: 'RELAY_TIMEOUT'` | Yes — increase timeout or re-poll; the spoke tx already landed. |
|
|
13
|
+
| `RELAY_FAILED` | Relay polling outage / unrecognised relay error. | `phase: 'relay'`, `relayCode` | Yes — exponential backoff. |
|
|
14
|
+
| `APPROVE_FAILED` | Token approval call failed. | `phase: 'approve'` | Sometimes — gas / RPC issues are retryable. |
|
|
15
|
+
| `ALLOWANCE_CHECK_FAILED` | Reading on-chain allowance failed. | `phase: 'allowanceCheck'` | Yes — read-only retry is cheap. |
|
|
16
|
+
| `GAS_ESTIMATION_FAILED` | Gas estimation returned an error. | `phase: 'gasEstimation'` | Yes — re-estimate is the norm. |
|
|
17
|
+
| `LOOKUP_FAILED` | Read-only on-chain query / off-chain config fetch. | `method`, `phase: 'lookup'` | Yes — read-only retry is cheap. |
|
|
18
|
+
| `EXTERNAL_API_ERROR` | Upstream API call failed (solver, backend). | `api: 'solver' \| 'backend'`; for solver: `solverCode`, `solverDetail` | Sometimes — depends on `solverCode`. |
|
|
19
|
+
| `UNKNOWN` | Last-resort catch in an outer `try`. | (none guaranteed) | Treat as unrecoverable; surface the underlying cause. |
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
type SodaxFeature =
|
|
25
|
+
| 'swap'
|
|
26
|
+
| 'moneyMarket'
|
|
27
|
+
| 'bridge'
|
|
28
|
+
| 'staking'
|
|
29
|
+
| 'migration'
|
|
30
|
+
| 'dex'
|
|
31
|
+
| 'partner'
|
|
32
|
+
| 'recovery';
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The `(feature, code)` pair is the canonical discriminator. Loggers tag both fields; switch statements branch on both.
|
|
36
|
+
|
|
37
|
+
### Phase tags (`error.context.phase`)
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
type SodaxPhase =
|
|
41
|
+
| 'validate' // pre-flight invariant
|
|
42
|
+
| 'intentCreation' // building intent / payload
|
|
43
|
+
| 'verify' // spoke verifyTxHash
|
|
44
|
+
| 'submit' // spoke→relay submit
|
|
45
|
+
| 'relay' // primary relayTxAndWaitPacket wait
|
|
46
|
+
| 'destinationExecution' // secondary watcher (migration's bnUSD waitUntilIntentExecuted)
|
|
47
|
+
| 'execution' // orchestrator-level catch
|
|
48
|
+
| 'postExecution' // swap-only post-relay solver step
|
|
49
|
+
| 'approve' // ERC20 approval call
|
|
50
|
+
| 'allowanceCheck' // on-chain allowance read
|
|
51
|
+
| 'gasEstimation' // gas-estimation read
|
|
52
|
+
| 'lookup'; // generic read-only query
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### `RelayCode` (`error.context.relayCode`)
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
type RelayCode =
|
|
59
|
+
| 'SUBMIT_TX_FAILED'
|
|
60
|
+
| 'RELAY_TIMEOUT'
|
|
61
|
+
| 'RELAY_POLLING_FAILED'
|
|
62
|
+
| 'UNKNOWN';
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
This is the lower-level relay-layer code that `mapRelayFailure` maps from. Surfaces on `error.context.relayCode` when the error originated in `IntentRelayApiService`.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
## Per-method error codes
|
|
71
|
+
|
|
72
|
+
Narrow code unions per public method. Use these for exhaustive `switch` discrimination.
|
|
73
|
+
|
|
74
|
+
### Common helper unions (used across features)
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
// 'create*Intent' methods
|
|
78
|
+
type CreateIntentErrorCode = 'VALIDATION_FAILED' | 'INTENT_CREATION_FAILED' | 'UNKNOWN';
|
|
79
|
+
|
|
80
|
+
// 'approve' methods
|
|
81
|
+
type ApproveErrorCode = 'VALIDATION_FAILED' | 'APPROVE_FAILED' | 'UNKNOWN';
|
|
82
|
+
|
|
83
|
+
// 'isAllowanceValid' methods
|
|
84
|
+
type AllowanceCheckErrorCode = 'VALIDATION_FAILED' | 'ALLOWANCE_CHECK_FAILED' | 'UNKNOWN';
|
|
85
|
+
|
|
86
|
+
// 'estimateGas' methods
|
|
87
|
+
type GasEstimationErrorCode = 'VALIDATION_FAILED' | 'GAS_ESTIMATION_FAILED' | 'UNKNOWN';
|
|
88
|
+
|
|
89
|
+
// All read-only lookups
|
|
90
|
+
type LookupErrorCode = 'VALIDATION_FAILED' | 'LOOKUP_FAILED' | 'UNKNOWN';
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Swap (`feature: 'swap'`)
|
|
94
|
+
|
|
95
|
+
| Method | Narrow code union |
|
|
96
|
+
|---|---|
|
|
97
|
+
| `createIntent` | `CreateIntentErrorCode` |
|
|
98
|
+
| `swap` | All of {`VALIDATION_FAILED`, `INTENT_CREATION_FAILED`, `EXECUTION_FAILED`, `TX_VERIFICATION_FAILED`, `TX_SUBMIT_FAILED`, `RELAY_TIMEOUT`, `RELAY_FAILED`, `EXTERNAL_API_ERROR`, `UNKNOWN`} |
|
|
99
|
+
| `postExecution` | `EXECUTION_FAILED \| EXTERNAL_API_ERROR \| UNKNOWN` (with `phase: 'postExecution'`) |
|
|
100
|
+
| `createLimitOrder`, `createLimitOrderIntent` | `CreateIntentErrorCode` |
|
|
101
|
+
| `cancelIntent`, `cancelLimitOrder` | `EXECUTION_FAILED \| VALIDATION_FAILED \| UNKNOWN` |
|
|
102
|
+
|
|
103
|
+
### Money Market (`feature: 'moneyMarket'`)
|
|
104
|
+
|
|
105
|
+
| Method | Narrow code union |
|
|
106
|
+
|---|---|
|
|
107
|
+
| `supply`, `borrow`, `withdraw`, `repay` | `VALIDATION_FAILED \| INTENT_CREATION_FAILED \| EXECUTION_FAILED \| TX_VERIFICATION_FAILED \| TX_SUBMIT_FAILED \| RELAY_TIMEOUT \| RELAY_FAILED \| UNKNOWN` (with `action` discriminator) |
|
|
108
|
+
| `createSupplyIntent`, `createBorrowIntent`, `createWithdrawIntent`, `createRepayIntent` | `CreateIntentErrorCode` |
|
|
109
|
+
| `approve` | `ApproveErrorCode` |
|
|
110
|
+
| `isAllowanceValid` | `AllowanceCheckErrorCode` |
|
|
111
|
+
| `estimateGas` | `GasEstimationErrorCode` |
|
|
112
|
+
| Read-only methods (reserves, user data, etc.) | `LookupErrorCode` |
|
|
113
|
+
|
|
114
|
+
### Staking (`feature: 'staking'`)
|
|
115
|
+
|
|
116
|
+
| Method | Narrow code union |
|
|
117
|
+
|---|---|
|
|
118
|
+
| `stake` | All exec codes including `TX_VERIFICATION_FAILED` (only stake calls verifyTxHash). |
|
|
119
|
+
| `unstake`, `instantUnstake`, `claim`, `cancelUnstake` | All exec codes minus `TX_VERIFICATION_FAILED`. |
|
|
120
|
+
| `approve` | `ApproveErrorCode` |
|
|
121
|
+
| `isAllowanceValid` | `AllowanceCheckErrorCode` |
|
|
122
|
+
| `getStakingInfo`, `getUnstakingInfo`, `getStakingConfig`, `getStakeRatio`, `getInstantUnstakeRatio`, `getConvertedAssets`, `getUnstakingInfoWithPenalty`, `getStakingInfoFromSpoke` | `LookupErrorCode` (with `method` discriminator) |
|
|
123
|
+
|
|
124
|
+
### Bridge (`feature: 'bridge'`)
|
|
125
|
+
|
|
126
|
+
| Method | Narrow code union |
|
|
127
|
+
|---|---|
|
|
128
|
+
| `bridge` | All exec codes. |
|
|
129
|
+
| `createBridgeIntent` | `CreateIntentErrorCode` |
|
|
130
|
+
| `approve` | `ApproveErrorCode` |
|
|
131
|
+
| `isAllowanceValid` | `AllowanceCheckErrorCode` |
|
|
132
|
+
| `getBridgeableAmount`, `getBridgeableTokens` | `LookupErrorCode` (with `method` discriminator) |
|
|
133
|
+
|
|
134
|
+
### DEX (`feature: 'dex'`)
|
|
135
|
+
|
|
136
|
+
| Method | Narrow code union |
|
|
137
|
+
|---|---|
|
|
138
|
+
| `assetService.deposit`, `assetService.withdraw` | All exec codes. |
|
|
139
|
+
| `clService.supplyLiquidity`, `clService.increaseLiquidity`, `clService.decreaseLiquidity`, `clService.claimRewards` | All exec codes. |
|
|
140
|
+
| `assetService.approve` | `ApproveErrorCode` |
|
|
141
|
+
| `assetService.isAllowanceValid` | `AllowanceCheckErrorCode` |
|
|
142
|
+
| `clService.getPoolData`, `clService.getPositionInfo`, `assetService.getDeposit` | `LookupErrorCode` |
|
|
143
|
+
|
|
144
|
+
### Migration (`feature: 'migration'`)
|
|
145
|
+
|
|
146
|
+
| Method | Narrow code union |
|
|
147
|
+
|---|---|
|
|
148
|
+
| `migratebnUSD` | All exec codes; `direction: 'forward' \| 'reverse'` on context. |
|
|
149
|
+
| `migrateIcxToSoda`, `revertMigrateSodaToIcx`, `migrateBaln` | All exec codes. |
|
|
150
|
+
| `createXxxIntent` (4 of these) | `CreateIntentErrorCode` |
|
|
151
|
+
| `approve` | `ApproveErrorCode` |
|
|
152
|
+
| `isAllowanceValid` | `AllowanceCheckErrorCode` |
|
|
153
|
+
| `getAvailableAmount` | `LookupErrorCode` |
|
|
154
|
+
|
|
155
|
+
### Partner (`feature: 'partner'`) and Recovery (`feature: 'recovery'`)
|
|
156
|
+
|
|
157
|
+
Both follow the same shape: action methods get the full exec union (`'EXECUTION_FAILED' \| 'INTENT_CREATION_FAILED' \| ...`), read methods get `LookupErrorCode`, approve methods get `ApproveErrorCode`.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
## Cross-references
|
|
163
|
+
|
|
164
|
+
- [`README.md`](README.md) — reference index.
|
|
165
|
+
- [`../architecture.md`](../architecture.md) § 7–8 — error model concepts.
|