@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,181 @@
|
|
|
1
|
+
# Token migration — `MigrationService`
|
|
2
|
+
|
|
3
|
+
Migration of legacy ICON ecosystem tokens to the SODAX hub. Three sub-services:
|
|
4
|
+
|
|
5
|
+
- **`IcxMigrationService`** — ICX/wICX → SODA (forward) and SODA → ICX (revert).
|
|
6
|
+
- **`BnUSDMigrationService`** — legacy bnUSD (ICON / Sui / Stellar) ↔ new bnUSD (EVM chains) via vault transformations.
|
|
7
|
+
- **`BalnSwapService`** — BALN → SODA with lockup periods (0–24 months) that multiply rewards (0.5x–1.5x).
|
|
8
|
+
|
|
9
|
+
Access: `sodax.migration`. Service class: `MigrationService` (with sub-services `sodax.migration.icxMigration`, `sodax.migration.bnUSDMigrationService`, `sodax.migration.balnSwapService`). Feature tag for errors: `'migration'`.
|
|
10
|
+
|
|
11
|
+
> Don't confuse this feature (the `MigrationService` SDK module) with the v1 → v2 SDK port itself. They share the word "migration" but are independent concerns. The v1 → v2 port playbook lives at [`features/migration.md`](../../../migration-v1-to-v2/knowledge/features/migration.md).
|
|
12
|
+
|
|
13
|
+
## How it works
|
|
14
|
+
|
|
15
|
+
All three sub-services follow the same pattern: deposit on a spoke chain → relay to hub → execute hub-side migration contract → deliver new token.
|
|
16
|
+
|
|
17
|
+
`MigrationService` exposes 11 async public methods:
|
|
18
|
+
|
|
19
|
+
- 4 orchestrators (full execution): `migratebnUSD`, `migrateIcxToSoda`, `revertMigrateSodaToIcx`, `migrateBaln`.
|
|
20
|
+
- 4 intent creators (raw or signed spoke tx, no full lifecycle): `createMigrateBnUSDIntent`, `createMigrateIcxToSodaIntent`, `createRevertMigrateSodaToIcxIntent`, `createMigrateBalnIntent`.
|
|
21
|
+
- `approve`, `isAllowanceValid` (action-discriminated like staking and money market).
|
|
22
|
+
- `getAvailableAmount` (read-only; `IcxMigrationService` only — checks how much SODA the user can claim from a partial migration).
|
|
23
|
+
|
|
24
|
+
`BalnSwapService` has additional lock-management methods that **still throw** (do not return `Result<T>`): `claim`, `claimUnstaked`, `stake`, `unstake`, `cancelUnstake`, `getDetailedUserLocks`. This is deliberate tech debt; future cleanup. Wrap them in `try/catch` until then.
|
|
25
|
+
|
|
26
|
+
## Public methods
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
sodax.migration.migratebnUSD<K>(action): Promise<Result<TxHashPair, SodaxError>>;
|
|
30
|
+
sodax.migration.migrateIcxToSoda<K>(action): Promise<Result<TxHashPair, SodaxError>>;
|
|
31
|
+
sodax.migration.revertMigrateSodaToIcx<K>(action): Promise<Result<TxHashPair, SodaxError>>;
|
|
32
|
+
sodax.migration.migrateBaln<K>(action): Promise<Result<TxHashPair, SodaxError>>;
|
|
33
|
+
|
|
34
|
+
sodax.migration.createMigrateBnUSDIntent<K, Raw>(...): Promise<Result<...>>;
|
|
35
|
+
// + 3 other createXxxIntent methods
|
|
36
|
+
|
|
37
|
+
sodax.migration.approve<K, Raw>(args): Promise<Result<TxReturnType<K, Raw>, SodaxError>>;
|
|
38
|
+
sodax.migration.isAllowanceValid<K, Raw>(args): Promise<Result<boolean, SodaxError>>;
|
|
39
|
+
|
|
40
|
+
sodax.migration.icxMigration.getAvailableAmount(): Promise<Result<bigint, SodaxError>>;
|
|
41
|
+
|
|
42
|
+
// BalnSwapService — STILL THROW (tech debt; not Result-wrapped):
|
|
43
|
+
sodax.migration.balnSwapService.claim(...): Promise<TxReturnType<K, false>>;
|
|
44
|
+
sodax.migration.balnSwapService.claimUnstaked(...): Promise<TxReturnType<K, false>>;
|
|
45
|
+
sodax.migration.balnSwapService.stake(...): Promise<TxReturnType<K, false>>;
|
|
46
|
+
sodax.migration.balnSwapService.unstake(...): Promise<TxReturnType<K, false>>;
|
|
47
|
+
sodax.migration.balnSwapService.cancelUnstake(...): Promise<TxReturnType<K, false>>;
|
|
48
|
+
sodax.migration.balnSwapService.getDetailedUserLocks(...): Promise<DetailedUserLocks>;
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Action params shape
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
type MigrationParams<K extends SpokeChainKey> = {
|
|
55
|
+
srcChainKey: K;
|
|
56
|
+
srcAddress: GetAddressType<K>;
|
|
57
|
+
amount: bigint;
|
|
58
|
+
dstAddress?: string;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
type UnifiedBnUSDMigrateParams<K> = MigrationParams<K> & {
|
|
62
|
+
srcToken: `0x${string}`; // legacy or new bnUSD; SDK detects direction from address
|
|
63
|
+
dstToken: `0x${string}`; // the other side
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
type IcxToSodaMigrateParams<K> = MigrationParams<K>;
|
|
67
|
+
type RevertSodaToIcxParams<K> = MigrationParams<K>;
|
|
68
|
+
type BalnSwapParams<K> = MigrationParams<K> & {
|
|
69
|
+
lockPeriodMonths: 0 | 1 | 2 | 3 | 6 | 12 | 18 | 24; // reward multiplier 0.5x – 1.5x
|
|
70
|
+
};
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Common call shapes
|
|
74
|
+
|
|
75
|
+
### bnUSD migrate (forward — legacy → new, e.g. ICON → BASE)
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
const result = await sodax.migration.migratebnUSD({
|
|
79
|
+
params: {
|
|
80
|
+
srcChainKey: ChainKeys.ICON_MAINNET,
|
|
81
|
+
srcAddress: 'hx…',
|
|
82
|
+
srcToken: '0x…', // legacy bnUSD on ICON
|
|
83
|
+
dstToken: '0x…', // new bnUSD on BASE
|
|
84
|
+
amount: parseUnits('100', 18),
|
|
85
|
+
dstAddress: '0x…',
|
|
86
|
+
},
|
|
87
|
+
raw: false,
|
|
88
|
+
walletProvider: iconWp,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
if (!result.ok) return;
|
|
92
|
+
const { srcChainTxHash, dstChainTxHash } = result.value;
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The SDK auto-detects direction from `(srcToken, dstToken)` addresses; the `direction` field surfaces on `error.context` if it fails (`'forward' | 'reverse'`).
|
|
96
|
+
|
|
97
|
+
### ICX → SODA
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
await sodax.migration.migrateIcxToSoda({
|
|
101
|
+
params: { srcChainKey: ChainKeys.ICON_MAINNET, srcAddress: 'hx…', amount },
|
|
102
|
+
raw: false,
|
|
103
|
+
walletProvider: iconWp,
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Revert SODA → ICX
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
await sodax.migration.revertMigrateSodaToIcx({
|
|
111
|
+
params: { srcChainKey: ChainKeys.SONIC_MAINNET, srcAddress: '0x…', amount },
|
|
112
|
+
raw: false,
|
|
113
|
+
walletProvider: sonicWp,
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### BALN → SODA with lockup
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
await sodax.migration.migrateBaln({
|
|
121
|
+
params: {
|
|
122
|
+
srcChainKey: ChainKeys.ICON_MAINNET,
|
|
123
|
+
srcAddress: 'hx…',
|
|
124
|
+
amount: parseUnits('1000', 18),
|
|
125
|
+
lockPeriodMonths: 12, // 1.0x base; 24 is 1.5x; 0 is 0.5x
|
|
126
|
+
},
|
|
127
|
+
raw: false,
|
|
128
|
+
walletProvider: iconWp,
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Approve / allowance — action-discriminated
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
await sodax.migration.approve({
|
|
136
|
+
params: { srcChainKey, srcAddress, amount, action: 'migratebnUSD' /* or 'migrateIcxToSoda' | 'revertMigrateSodaToIcx' | 'migrateBaln' */ },
|
|
137
|
+
raw: false,
|
|
138
|
+
walletProvider,
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### BALN lock management (carve-out — still throws)
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
try {
|
|
146
|
+
const tx = await sodax.migration.balnSwapService.stake({ /* … */ });
|
|
147
|
+
} catch (e) {
|
|
148
|
+
// Handle as v1-style throw. Result wrapping for these methods is on the roadmap.
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Return shapes
|
|
153
|
+
|
|
154
|
+
| Method | Success type |
|
|
155
|
+
|---|---|
|
|
156
|
+
| 4 orchestrators (`migratebnUSD`, `migrateIcxToSoda`, `revertMigrateSodaToIcx`, `migrateBaln`) | `TxHashPair` |
|
|
157
|
+
| 4 intent creators | `CreateIntentResult<K, Raw>` |
|
|
158
|
+
| `approve` | `TxReturnType<K, Raw>` |
|
|
159
|
+
| `isAllowanceValid` | `boolean` |
|
|
160
|
+
| `getAvailableAmount` | `bigint` |
|
|
161
|
+
| `BalnSwapService.claim` etc. | `TxReturnType<K, false>` (raw, not `Result`-wrapped) |
|
|
162
|
+
|
|
163
|
+
## Error codes
|
|
164
|
+
|
|
165
|
+
`feature: 'migration'`. Per-method narrow unions:
|
|
166
|
+
|
|
167
|
+
| Method | Codes | `error.context.action` | Notes |
|
|
168
|
+
|---|---|---|---|
|
|
169
|
+
| `migratebnUSD` | full exec set incl. `TX_VERIFICATION_FAILED` | `'migratebnUSD'` | `error.context.direction: 'forward' \| 'reverse'`. Has secondary `phase: 'destinationExecution'` for the bnUSD `waitUntilIntentExecuted` watcher. |
|
|
170
|
+
| `migrateIcxToSoda` | full exec set | `'migrateIcxToSoda'` | |
|
|
171
|
+
| `revertMigrateSodaToIcx` | full exec set | `'revertMigrateSodaToIcx'` | |
|
|
172
|
+
| `migrateBaln` | full exec set | `'migrateBaln'` | |
|
|
173
|
+
| `create*Intent` | `VALIDATION_FAILED`, `INTENT_CREATION_FAILED`, `UNKNOWN` | matches | |
|
|
174
|
+
| `approve` | `VALIDATION_FAILED`, `APPROVE_FAILED`, `UNKNOWN` | matches | |
|
|
175
|
+
| `isAllowanceValid` | `VALIDATION_FAILED`, `ALLOWANCE_CHECK_FAILED`, `UNKNOWN` | n/a | |
|
|
176
|
+
| `getAvailableAmount` | `VALIDATION_FAILED`, `LOOKUP_FAILED`, `UNKNOWN` | n/a | `method: 'getAvailableAmount'` |
|
|
177
|
+
|
|
178
|
+
## Cross-references
|
|
179
|
+
|
|
180
|
+
- v1 → v2 migration of this feature: [`features/migration.md`](../../../migration-v1-to-v2/knowledge/features/migration.md).
|
|
181
|
+
- Architecture (relay layer's `phase: 'destinationExecution'` for bnUSD): [`../architecture.md`](../architecture.md) § 9.
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Money Market — `MoneyMarketService`
|
|
2
|
+
|
|
3
|
+
Cross-chain lending and borrowing. Supply, borrow, withdraw, repay across 19 spoke chains. Position state lives on the hub.
|
|
4
|
+
|
|
5
|
+
Access: `sodax.moneyMarket`. Service class: `MoneyMarketService`. Feature tag for errors: `'moneyMarket'`.
|
|
6
|
+
|
|
7
|
+
## How it works
|
|
8
|
+
|
|
9
|
+
A user supplies on a spoke chain; the SDK relays the deposit to the hub, where the position is recorded against the user's hub wallet abstraction. Borrow can deliver funds back to the same chain (same-chain borrow) or to a different spoke chain (cross-chain borrow). Withdraw and repay reverse the flow.
|
|
10
|
+
|
|
11
|
+
aTokens (ERC4626 receipt tokens) live on the hub and represent the user's share of each reserve. Use `sodax.moneyMarket.getAToken(...)` to look them up.
|
|
12
|
+
|
|
13
|
+
## Public methods
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
// Mutations
|
|
17
|
+
sodax.moneyMarket.supply<K>(action): Promise<Result<TxHashPair, SodaxError>>;
|
|
18
|
+
sodax.moneyMarket.borrow<K>(action): Promise<Result<TxHashPair, SodaxError>>;
|
|
19
|
+
sodax.moneyMarket.withdraw<K>(action): Promise<Result<TxHashPair, SodaxError>>;
|
|
20
|
+
sodax.moneyMarket.repay<K>(action): Promise<Result<TxHashPair, SodaxError>>;
|
|
21
|
+
|
|
22
|
+
// Intent creators (raw-tx variant)
|
|
23
|
+
sodax.moneyMarket.createSupplyIntent<K, Raw>(...): Promise<Result<...>>;
|
|
24
|
+
sodax.moneyMarket.createBorrowIntent<K, Raw>(...): Promise<Result<...>>;
|
|
25
|
+
sodax.moneyMarket.createWithdrawIntent<K, Raw>(...): Promise<Result<...>>;
|
|
26
|
+
sodax.moneyMarket.createRepayIntent<K, Raw>(...): Promise<Result<...>>;
|
|
27
|
+
|
|
28
|
+
// Approve + allowance (action-discriminated)
|
|
29
|
+
sodax.moneyMarket.approve<K, Raw>(args): Promise<Result<TxReturnType<K, Raw>, SodaxError>>;
|
|
30
|
+
sodax.moneyMarket.isAllowanceValid<K>(args): Promise<Result<boolean, SodaxError>>;
|
|
31
|
+
|
|
32
|
+
// Estimation
|
|
33
|
+
sodax.moneyMarket.estimateGas<K>(params): Promise<Result<GetEstimateGasReturnType<K>, SodaxError>>;
|
|
34
|
+
|
|
35
|
+
// Reads (sync — config-derived, no I/O)
|
|
36
|
+
sodax.moneyMarket.getSupportedTokens(): GetMoneyMarketTokensApiResponse;
|
|
37
|
+
sodax.moneyMarket.getSupportedTokensByChainId(chainKey): readonly XToken[];
|
|
38
|
+
sodax.moneyMarket.getSupportedReserves(): readonly Address[];
|
|
39
|
+
|
|
40
|
+
// Hub-side calldata builders (Hex outputs; pre-flight inspection / custom orchestration)
|
|
41
|
+
sodax.moneyMarket.buildSupplyData(srcChainKey, fromToken, amount, toHubAddress): Hex;
|
|
42
|
+
sodax.moneyMarket.buildBorrowData(...): Hex;
|
|
43
|
+
sodax.moneyMarket.buildWithdrawData(...): Hex;
|
|
44
|
+
sodax.moneyMarket.buildRepayData(...): Hex;
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
For per-position user reads (reserves data, user reserves data, formatted summaries, aToken balances, etc.) the entrypoint is `sodax.backendApi`, not `MoneyMarketService` — see [`backend-api.md`](backend-api.md) for `getMoneyMarketPosition`, `getAllMoneyMarketAssets`, `getMoneyMarketAsset`, `getMoneyMarketAssetBorrowers`, `getMoneyMarketAssetSuppliers`, `getAllMoneyMarketBorrowers`.
|
|
48
|
+
|
|
49
|
+
## Action params shape
|
|
50
|
+
|
|
51
|
+
`MoneyMarketParams<K>` is the shared base:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
type MoneyMarketParams<K extends SpokeChainKey> = {
|
|
55
|
+
srcChainKey: K;
|
|
56
|
+
srcAddress: GetAddressType<K>;
|
|
57
|
+
token: `0x${string}`; // hub asset address
|
|
58
|
+
amount: bigint;
|
|
59
|
+
};
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Per-action params:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
type MoneyMarketSupplyParams<K> = MoneyMarketParams<K> & { action: 'supply' };
|
|
66
|
+
type MoneyMarketWithdrawParams<K> = MoneyMarketParams<K> & { action: 'withdraw' };
|
|
67
|
+
|
|
68
|
+
type MoneyMarketBorrowParams<K> = MoneyMarketParams<K> & {
|
|
69
|
+
action: 'borrow';
|
|
70
|
+
dstChainKey?: SpokeChainKey; // delivery chain; defaults to srcChainKey
|
|
71
|
+
dstAddress?: string;
|
|
72
|
+
};
|
|
73
|
+
type MoneyMarketRepayParams<K> = MoneyMarketParams<K> & {
|
|
74
|
+
action: 'repay';
|
|
75
|
+
dstChainKey?: SpokeChainKey; // debt chain; defaults to srcChainKey
|
|
76
|
+
dstAddress?: string;
|
|
77
|
+
};
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Common call shapes
|
|
81
|
+
|
|
82
|
+
### Supply (same-chain)
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
const result = await sodax.moneyMarket.supply({
|
|
86
|
+
params: {
|
|
87
|
+
srcChainKey: ChainKeys.ARBITRUM_MAINNET,
|
|
88
|
+
srcAddress: '0x…',
|
|
89
|
+
token: USDC.address,
|
|
90
|
+
amount: parseUnits('100', 6),
|
|
91
|
+
action: 'supply',
|
|
92
|
+
},
|
|
93
|
+
raw: false,
|
|
94
|
+
walletProvider: evmWp,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
if (!result.ok) return;
|
|
98
|
+
const { srcChainTxHash, dstChainTxHash } = result.value;
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Borrow (cross-chain)
|
|
102
|
+
|
|
103
|
+
Borrow on Arbitrum, deliver USDC to Stellar:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
await sodax.moneyMarket.borrow({
|
|
107
|
+
params: {
|
|
108
|
+
srcChainKey: ChainKeys.ARBITRUM_MAINNET,
|
|
109
|
+
srcAddress: '0x…',
|
|
110
|
+
token: USDC_ARBITRUM.address,
|
|
111
|
+
amount: parseUnits('50', 6),
|
|
112
|
+
action: 'borrow',
|
|
113
|
+
dstChainKey: ChainKeys.STELLAR_MAINNET,
|
|
114
|
+
dstAddress: 'G…',
|
|
115
|
+
},
|
|
116
|
+
raw: false,
|
|
117
|
+
walletProvider: evmWp,
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Same-chain borrow: omit `dstChainKey` and `dstAddress`.
|
|
122
|
+
|
|
123
|
+
### Repay (cross-chain — pay from a different chain than the debt)
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
await sodax.moneyMarket.repay({
|
|
127
|
+
params: {
|
|
128
|
+
srcChainKey: ChainKeys.BASE_MAINNET, // funds come from here
|
|
129
|
+
srcAddress: '0x…',
|
|
130
|
+
token: USDC_BASE.address,
|
|
131
|
+
amount: parseUnits('50', 6),
|
|
132
|
+
action: 'repay',
|
|
133
|
+
dstChainKey: ChainKeys.ARBITRUM_MAINNET, // debt lives here
|
|
134
|
+
dstAddress: '0x…',
|
|
135
|
+
},
|
|
136
|
+
raw: false,
|
|
137
|
+
walletProvider: baseWp, // wallet signs on the FROM chain (BASE)
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Approve / allowance check
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
await sodax.moneyMarket.approve({
|
|
145
|
+
params: { srcChainKey, srcAddress, token, amount, action: 'supply' },
|
|
146
|
+
raw: false,
|
|
147
|
+
walletProvider: evmWp,
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const allowed = await sodax.moneyMarket.isAllowanceValid({
|
|
151
|
+
params: { srcChainKey, srcAddress, token, amount, action: 'supply' },
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
The `action` field routes to the right token under the hood — relevant for repay where the spent token may differ from the supplied token.
|
|
156
|
+
|
|
157
|
+
## Return shapes
|
|
158
|
+
|
|
159
|
+
| Method | Success type |
|
|
160
|
+
|---|---|
|
|
161
|
+
| `supply`, `borrow`, `withdraw`, `repay` | `TxHashPair` = `{ srcChainTxHash, dstChainTxHash }` |
|
|
162
|
+
| `create*Intent` | `CreateIntentResult<K, Raw>` |
|
|
163
|
+
| `approve` | `TxReturnType<K, Raw>` |
|
|
164
|
+
| `isAllowanceValid` | `boolean` |
|
|
165
|
+
| `estimateGas` | `GetEstimateGasReturnType<K>` (chain-family-specific) |
|
|
166
|
+
| `getSupportedTokens` | `GetMoneyMarketTokensApiResponse` (record of chains → token arrays) |
|
|
167
|
+
| `getSupportedTokensByChainId` | `readonly XToken[]` |
|
|
168
|
+
| `getSupportedReserves` | `readonly Address[]` |
|
|
169
|
+
| `buildSupplyData` / `buildBorrowData` / `buildWithdrawData` / `buildRepayData` | `Hex` (calldata for hub-side calls) |
|
|
170
|
+
|
|
171
|
+
> Every cross-chain mutation across the SDK (bridge, staking, dex, migration, MM) returns `TxHashPair = { srcChainTxHash, dstChainTxHash }` — there is no array-form variant in v2.
|
|
172
|
+
|
|
173
|
+
## Error codes
|
|
174
|
+
|
|
175
|
+
`feature: 'moneyMarket'`. Per-method narrow unions:
|
|
176
|
+
|
|
177
|
+
| Method | Codes | `error.context.action` |
|
|
178
|
+
|---|---|---|
|
|
179
|
+
| `supply` | full exec set | `'supply'` |
|
|
180
|
+
| `borrow` | full exec set | `'borrow'` |
|
|
181
|
+
| `withdraw` | full exec set | `'withdraw'` |
|
|
182
|
+
| `repay` | full exec set | `'repay'` |
|
|
183
|
+
| `create*Intent` | `VALIDATION_FAILED`, `INTENT_CREATION_FAILED`, `UNKNOWN` | matches action |
|
|
184
|
+
| `approve` | `VALIDATION_FAILED`, `APPROVE_FAILED`, `UNKNOWN` | matches action |
|
|
185
|
+
| `isAllowanceValid` | `VALIDATION_FAILED`, `ALLOWANCE_CHECK_FAILED`, `UNKNOWN` | matches action |
|
|
186
|
+
| Read methods | `VALIDATION_FAILED`, `LOOKUP_FAILED`, `UNKNOWN` | (use `error.context.method`) |
|
|
187
|
+
|
|
188
|
+
"Full exec set" = `VALIDATION_FAILED \| INTENT_CREATION_FAILED \| EXECUTION_FAILED \| TX_VERIFICATION_FAILED \| TX_SUBMIT_FAILED \| RELAY_TIMEOUT \| RELAY_FAILED \| UNKNOWN`.
|
|
189
|
+
|
|
190
|
+
## RAY precision math
|
|
191
|
+
|
|
192
|
+
Aave's RAY precision (27 decimals) is used for interest calculations under the hood. Raw RAY values flow through `BackendApiService.getMoneyMarketAsset` / `getMoneyMarketPosition` (via `sodax.backendApi`); pre-formatted user-facing values come from the same backend service. Don't simplify the precision handling — porting Aave's `RayMath`/`PercentageMath` losslessly is a load-bearing requirement.
|
|
193
|
+
|
|
194
|
+
## Cross-references
|
|
195
|
+
|
|
196
|
+
- v1 → v2 money market migration: [`features/money-market.md`](../../../migration-v1-to-v2/knowledge/features/money-market.md).
|
|
197
|
+
- Architecture (hub-side wallet abstraction, ConfigService): [`../architecture.md`](../architecture.md) §§ 3, 4.
|
|
198
|
+
- Stellar destinations need a trustline: [`../chain-specifics.md`](../chain-specifics.md).
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Partner — `PartnerService`
|
|
2
|
+
|
|
3
|
+
Partner-fee handling. `PartnerService` itself only exposes `feeClaim: PartnerFeeClaimService` and `config: ConfigService` as public fields. Every operation lives on `sodax.partners.feeClaim`.
|
|
4
|
+
|
|
5
|
+
Access: `sodax.partners`. Service class: `PartnerService` (operations on `sodax.partners.feeClaim`). Feature tag for errors: `'partner'`.
|
|
6
|
+
|
|
7
|
+
## Methods (all on `sodax.partners.feeClaim`)
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
// Token approval
|
|
11
|
+
sodax.partners.feeClaim.isTokenApproved({ token, srcAddress }): Promise<Result<boolean, Error>>;
|
|
12
|
+
sodax.partners.feeClaim.approveToken<Raw>(args): Promise<Result<TxReturnType, Error>>;
|
|
13
|
+
|
|
14
|
+
// Auto-swap preferences (whether partner-collected fees auto-swap into a target asset)
|
|
15
|
+
sodax.partners.feeClaim.getAutoSwapPreferences(queryAddress): Promise<Result<AutoSwapPreferences, Error>>;
|
|
16
|
+
sodax.partners.feeClaim.setSwapPreference<K, Raw>(args): Promise<Result<TxReturnType, Error>>;
|
|
17
|
+
|
|
18
|
+
// Fee claim flows
|
|
19
|
+
sodax.partners.feeClaim.swap(args): Promise<Result<...>>; // immediate fee swap
|
|
20
|
+
sodax.partners.feeClaim.createIntentAutoSwap<Raw>(args): Promise<Result<...>>; // intent-driven auto-swap
|
|
21
|
+
|
|
22
|
+
// Reads
|
|
23
|
+
sodax.partners.feeClaim.fetchAssetsBalances(args): Promise<Result<...>>;
|
|
24
|
+
sodax.partners.feeClaim.getOriginalAssetAddress(chainId, hubAsset): OriginalAssetAddress | undefined;
|
|
25
|
+
sodax.partners.feeClaim.getSpokeTokenFromOriginalAssetAddress(...): /* … */;
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Common call shape
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
// 1. Check whether the partner's fee token is approved on the hub:
|
|
32
|
+
const approved = await sodax.partners.feeClaim.isTokenApproved({
|
|
33
|
+
token: '0x…', // hub asset address
|
|
34
|
+
srcAddress: partnerAddress,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// 2. Approve once if not:
|
|
38
|
+
if (approved.ok && !approved.value) {
|
|
39
|
+
await sodax.partners.feeClaim.approveToken({
|
|
40
|
+
params: { token: '0x…', amount: 2n ** 256n - 1n },
|
|
41
|
+
raw: false,
|
|
42
|
+
walletProvider: sonicWp,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 3. Configure auto-swap preference (one-time):
|
|
47
|
+
await sodax.partners.feeClaim.setSwapPreference({
|
|
48
|
+
params: { /* preference fields */ },
|
|
49
|
+
raw: false,
|
|
50
|
+
walletProvider: sonicWp,
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Error codes
|
|
55
|
+
|
|
56
|
+
`feature: 'partner'`. Action methods get the full exec set; reads get `LookupErrorCode` partitioned by `error.context.method`.
|
|
57
|
+
|
|
58
|
+
## Cross-references
|
|
59
|
+
|
|
60
|
+
- v1 → v2 migration of `PartnerService`: [`features/partner.md`](../../../migration-v1-to-v2/knowledge/features/partner.md).
|
|
61
|
+
- Hub-wallet asset recovery (separate service): [`./recovery.md`](recovery.md).
|
|
62
|
+
- Backend HTTP client (separate service): [`./backend-api.md`](backend-api.md).
|
|
63
|
+
- Error model context fields (`error.context.api`, `error.context.method`): [`../reference/`](../reference/) § 3.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Recovery — `RecoveryService`
|
|
2
|
+
|
|
3
|
+
Withdraw stuck assets from a user's hub-wallet abstraction back to a spoke chain. Useful when a cross-chain operation deposited to the hub but the destination step failed (e.g. relay timeout after the spoke tx landed).
|
|
4
|
+
|
|
5
|
+
Access: `sodax.recovery`. Service class: `RecoveryService`. Feature tag for errors: `'recovery'`.
|
|
6
|
+
|
|
7
|
+
## Methods
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
// Read: list balances of all known hub assets in a user's hub wallet abstraction.
|
|
11
|
+
sodax.recovery.fetchHubAssetBalances(args): Promise<Result<HubAssetBalance[], SodaxError>>;
|
|
12
|
+
|
|
13
|
+
// Mutation: withdraw a single hub asset back to a spoke chain.
|
|
14
|
+
// Returns a tx-pair when raw: false (the hub-side spend + the relayed spoke-side receive).
|
|
15
|
+
sodax.recovery.withdrawHubAsset<K extends SpokeChainKey, Raw extends boolean>(
|
|
16
|
+
action: WithdrawHubAssetAction<K, Raw>,
|
|
17
|
+
): Promise<Result<TxReturnType<K, Raw>, SodaxError>>;
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Common call shape
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
// 1. Find what's stuck on the hub for this user:
|
|
24
|
+
const balances = await sodax.recovery.fetchHubAssetBalances({ /* user / hub-wallet args */ });
|
|
25
|
+
if (!balances.ok || balances.value.length === 0) return;
|
|
26
|
+
|
|
27
|
+
// 2. Withdraw one entry back to a spoke chain:
|
|
28
|
+
const result = await sodax.recovery.withdrawHubAsset({
|
|
29
|
+
params: {
|
|
30
|
+
/* hub-asset address, amount, destination spoke chain key, destination address */
|
|
31
|
+
},
|
|
32
|
+
raw: false,
|
|
33
|
+
walletProvider: sonicWp,
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Error codes
|
|
38
|
+
|
|
39
|
+
`feature: 'recovery'`. The mutation method returns the full exec set (including relay codes); the read method returns `LookupErrorCode` partitioned by `error.context.method`.
|
|
40
|
+
|
|
41
|
+
## When to use
|
|
42
|
+
|
|
43
|
+
Recovery is a workaround for failed cross-chain operations. Best used **after** investigating why the original operation failed — relay timeouts may resolve on retry; structural failures need fixing first.
|
|
44
|
+
|
|
45
|
+
## Cross-references
|
|
46
|
+
|
|
47
|
+
- v1 → v2 migration of `RecoveryService`: [`features/recovery.md`](../../../migration-v1-to-v2/knowledge/features/recovery.md) (note: service is new in v2 — no v1 equivalent).
|
|
48
|
+
- Partner-fee handling (separate service): [`./partner.md`](partner.md).
|
|
49
|
+
- Backend HTTP client (separate service): [`./backend-api.md`](backend-api.md).
|
|
50
|
+
- Error model context fields: [`../reference/`](../reference/) § 3.
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# Staking — `StakingService`
|
|
2
|
+
|
|
3
|
+
SODA token staking via an ERC4626 vault (xSoda). Stake, unstake (with penalty curve), instant unstake (slippage), claim, cancel-unstake. All operations are cross-chain — staking writes happen on the hub even when the user is on a spoke chain.
|
|
4
|
+
|
|
5
|
+
Access: `sodax.staking`. Service class: `StakingService`. Feature tag for errors: `'staking'`.
|
|
6
|
+
|
|
7
|
+
## How it works
|
|
8
|
+
|
|
9
|
+
- **SODA** (the staked asset) → **xSoda** (ERC4626 vault shares, proportional to current exchange rate).
|
|
10
|
+
- **Unstake** has a configurable waiting period with linear penalty (max 1–100%).
|
|
11
|
+
- **Instant unstake** bypasses the waiting period but pays slippage (via `StakingRouter`).
|
|
12
|
+
- **Claim** redeems SODA after the unstaking period expires.
|
|
13
|
+
- **Cancel unstake** restores xSoda from a pending unstake request before claim.
|
|
14
|
+
|
|
15
|
+
## Public methods
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
sodax.staking.stake<K>(action: StakeAction<K, false>): Promise<Result<TxHashPair, SodaxError>>;
|
|
19
|
+
sodax.staking.unstake<K>(action: UnstakeAction<K, false>): Promise<Result<TxHashPair, SodaxError>>;
|
|
20
|
+
sodax.staking.instantUnstake<K>(action: InstantUnstakeAction<K, false>): Promise<Result<TxHashPair, SodaxError>>;
|
|
21
|
+
sodax.staking.claim<K>(action: ClaimAction<K, false>): Promise<Result<TxHashPair, SodaxError>>;
|
|
22
|
+
sodax.staking.cancelUnstake<K>(action: CancelUnstakeAction<K, false>): Promise<Result<TxHashPair, SodaxError>>;
|
|
23
|
+
|
|
24
|
+
sodax.staking.createStakeIntent<K, Raw>(...): Promise<Result<...>>;
|
|
25
|
+
// + the 4 other createXxxIntent methods
|
|
26
|
+
|
|
27
|
+
sodax.staking.approve<K, Raw>(args): Promise<Result<TxReturnType<K, Raw>, SodaxError>>;
|
|
28
|
+
sodax.staking.isAllowanceValid<K, Raw>(args): Promise<Result<boolean, SodaxError>>;
|
|
29
|
+
|
|
30
|
+
// Reads (hub-only — no chain context needed):
|
|
31
|
+
sodax.staking.getStakingConfig(): Promise<Result<StakingConfig, SodaxError>>;
|
|
32
|
+
sodax.staking.getStakeRatio(amount): Promise<Result<[bigint, bigint], SodaxError>>;
|
|
33
|
+
// value: [xSodaAmount, previewDepositAmount]
|
|
34
|
+
sodax.staking.getInstantUnstakeRatio(amount): Promise<Result<bigint, SodaxError>>;
|
|
35
|
+
sodax.staking.getConvertedAssets(amount): Promise<Result<bigint, SodaxError>>;
|
|
36
|
+
|
|
37
|
+
// Reads (hub-address — caller already has the hub wallet):
|
|
38
|
+
sodax.staking.getStakingInfo(hubAddress: Address): Promise<Result<StakingInfo, SodaxError>>;
|
|
39
|
+
|
|
40
|
+
// Reads (cross-chain — derive hub wallet from src chain):
|
|
41
|
+
sodax.staking.getStakingInfoFromSpoke(srcAddress, srcChainKey): Promise<Result<StakingInfo, SodaxError>>;
|
|
42
|
+
// internally calls hubProvider.getUserHubWalletAddress(srcAddress, srcChainKey), then delegates to getStakingInfo
|
|
43
|
+
sodax.staking.getUnstakingInfo(srcAddress, srcChainKey): Promise<Result<UnstakingInfo, SodaxError>>;
|
|
44
|
+
// value: { userUnstakeSodaRequests: UserUnstakeInfo[]; totalUnstaking: bigint }
|
|
45
|
+
sodax.staking.getUnstakingInfoWithPenalty(srcAddress, srcChainKey): Promise<Result<UnstakingInfo & { requestsWithPenalty: UnstakeRequestWithPenalty[] }, SodaxError>>;
|
|
46
|
+
// each request adds penalty, penaltyPercentage, claimableAmount
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Action params shape
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
type StakeParams<K extends SpokeChainKey> = {
|
|
53
|
+
srcChainKey: K;
|
|
54
|
+
srcAddress: GetAddressType<K>;
|
|
55
|
+
amount: bigint;
|
|
56
|
+
minReceive: bigint; // min xSoda after slippage; gate against bad rates
|
|
57
|
+
action: 'stake';
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
type UnstakeParams<K> = { srcChainKey: K; srcAddress; amount: bigint; action: 'unstake' };
|
|
61
|
+
type InstantUnstakeParams<K> = { srcChainKey: K; srcAddress; amount: bigint; minAmount: bigint; action: 'instantUnstake' };
|
|
62
|
+
type ClaimParams<K> = { srcChainKey: K; srcAddress; requestId: bigint; amount: bigint; action: 'claim' };
|
|
63
|
+
type CancelUnstakeParams<K> = { srcChainKey: K; srcAddress; requestId: bigint; action: 'cancelUnstake' };
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`StakingParamsUnion<K, Raw>` is the union of all 5; consumed by `staking.approve` and `staking.isAllowanceValid` (action-discriminated).
|
|
67
|
+
|
|
68
|
+
## Common call shapes
|
|
69
|
+
|
|
70
|
+
### Stake
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
const result = await sodax.staking.stake({
|
|
74
|
+
params: {
|
|
75
|
+
srcChainKey: ChainKeys.ARBITRUM_MAINNET,
|
|
76
|
+
srcAddress: '0x…',
|
|
77
|
+
amount: parseUnits('100', 18), // 100 SODA
|
|
78
|
+
minReceive: parseUnits('99', 18), // expect ~1% slippage tolerance
|
|
79
|
+
action: 'stake',
|
|
80
|
+
},
|
|
81
|
+
raw: false,
|
|
82
|
+
walletProvider: evmWp,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
if (!result.ok) return;
|
|
86
|
+
const { srcChainTxHash, dstChainTxHash } = result.value;
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Unstake (with penalty curve)
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
await sodax.staking.unstake({
|
|
93
|
+
params: { srcChainKey, srcAddress, amount: xSodaAmount, action: 'unstake' },
|
|
94
|
+
raw: false,
|
|
95
|
+
walletProvider,
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Creates a pending unstake request. After the staking period expires, call `claim`. Use `getUnstakingInfoWithPenalty` to see the current penalty for early withdrawal.
|
|
100
|
+
|
|
101
|
+
### Instant unstake
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
await sodax.staking.instantUnstake({
|
|
105
|
+
params: {
|
|
106
|
+
srcChainKey, srcAddress,
|
|
107
|
+
amount: xSodaAmount,
|
|
108
|
+
minAmount: minSodaAfterSlippage,
|
|
109
|
+
action: 'instantUnstake',
|
|
110
|
+
},
|
|
111
|
+
raw: false,
|
|
112
|
+
walletProvider,
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Bypasses the waiting period; pays slippage via `StakingRouter`.
|
|
117
|
+
|
|
118
|
+
### Approve / allowance — action-discriminated
|
|
119
|
+
|
|
120
|
+
The `approve` method routes by `params.action` to approve the right token (SODA for `stake`, xSoda for `unstake` and `instantUnstake`):
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
await sodax.staking.approve({
|
|
124
|
+
params: { srcChainKey, srcAddress, amount, action: 'stake' /* or 'unstake' or 'instantUnstake' */ },
|
|
125
|
+
raw: false,
|
|
126
|
+
walletProvider,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
const allowed = await sodax.staking.isAllowanceValid({
|
|
130
|
+
params: { srcChainKey, srcAddress, amount, action: 'stake' },
|
|
131
|
+
raw: true, // read-only
|
|
132
|
+
});
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Return shapes
|
|
136
|
+
|
|
137
|
+
| Method | Success type |
|
|
138
|
+
|---|---|
|
|
139
|
+
| `stake`, `unstake`, `instantUnstake`, `claim`, `cancelUnstake` | `TxHashPair` |
|
|
140
|
+
| `create*Intent` | `CreateIntentResult<K, Raw>` |
|
|
141
|
+
| `approve` | `TxReturnType<K, Raw>` |
|
|
142
|
+
| `isAllowanceValid` | `boolean` |
|
|
143
|
+
| `getStakingConfig` | `{ unstakingPeriod, maxPenalty, minPenalty, /* … */ }` |
|
|
144
|
+
| `getStakeRatio` | `[xSodaAmount: bigint, previewDepositAmount: bigint]` (estimated xSoda shares + vault's `previewDeposit` preview) |
|
|
145
|
+
| `getInstantUnstakeRatio` | `bigint` |
|
|
146
|
+
| `getConvertedAssets` | `bigint` (SODA per xSoda) |
|
|
147
|
+
| `getStakingInfo` | `StakingInfo` (totals + user's xSoda balance + SODA value). Takes a hub address directly. |
|
|
148
|
+
| `getStakingInfoFromSpoke` | `StakingInfo` (same shape). Takes `(srcAddress, srcChainKey)`; resolves hub wallet internally. |
|
|
149
|
+
| `getUnstakingInfo` | `UnstakingInfo` (object; carries `userUnstakeSodaRequests` array + aggregate amount) |
|
|
150
|
+
| `getUnstakingInfoWithPenalty` | `UnstakingInfo & { requestsWithPenalty: UnstakeRequestWithPenalty[] }` (each entry adds `penalty`, `penaltyPercentage`, `claimableAmount`) |
|
|
151
|
+
|
|
152
|
+
> All 5 mutation methods return `TxHashPair = { srcChainTxHash, dstChainTxHash }` because the SDK relays spoke→hub internally. When the user is already on the hub, both fields hold the same hash.
|
|
153
|
+
|
|
154
|
+
## Error codes
|
|
155
|
+
|
|
156
|
+
`feature: 'staking'`. Per-method narrow unions:
|
|
157
|
+
|
|
158
|
+
| Method | Codes | Action |
|
|
159
|
+
|---|---|---|
|
|
160
|
+
| `stake` | full exec set incl. `TX_VERIFICATION_FAILED` (only stake calls verifyTxHash) | `'stake'` |
|
|
161
|
+
| `unstake`, `instantUnstake`, `claim`, `cancelUnstake` | full exec set minus `TX_VERIFICATION_FAILED` | matches action |
|
|
162
|
+
| `approve` | `VALIDATION_FAILED`, `APPROVE_FAILED`, `UNKNOWN` | matches action |
|
|
163
|
+
| `isAllowanceValid` | `VALIDATION_FAILED`, `ALLOWANCE_CHECK_FAILED`, `UNKNOWN` | matches action |
|
|
164
|
+
| Read methods (8 of them) | `VALIDATION_FAILED`, `LOOKUP_FAILED`, `UNKNOWN` | (use `error.context.method`) |
|
|
165
|
+
|
|
166
|
+
`StakingLogic` (a static utility class for contract encoding and on-chain reads) keeps its throw-on-error contract — wrapping happens only in `StakingService` public methods.
|
|
167
|
+
|
|
168
|
+
## Cross-references
|
|
169
|
+
|
|
170
|
+
- v1 → v2 staking migration: [`features/staking.md`](../../../migration-v1-to-v2/knowledge/features/staking.md).
|
|
171
|
+
- ERC4626 vault concept (xSoda): see SODAX docs site or `@sodax/sdk` source.
|