@sodax/sdk 2.0.0-rc.1 → 2.0.0-rc.3

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.
@@ -1,46 +1,137 @@
1
1
  # `SodaxConfig` constructor reshape
2
2
 
3
- The v2 `Sodax` constructor accepts a `DeepPartial<SodaxConfig>`. Several config fields renamed or moved between v1 and v2; if your project passed a custom config, check these:
3
+ The v2 `Sodax` constructor accepts a `DeepPartial<SodaxConfig>`. Several config fields renamed, moved, or were added between v1 and v2; if your project passed a custom config, check these.
4
4
 
5
- | v1 location | v2 location |
6
- |---|---|
7
- | `SodaxConfig.swaps` (held solver endpoints AND supported tokens) | Split into two: `SodaxConfig.swaps` (now `SwapsConfig` — supported tokens per chain) and `SodaxConfig.solver` (`{ intentsContract, solverApiEndpoint, protocolIntentsContract }`). |
8
- | `SodaxConfig.rpcConfig` (flat object: one URL per chain field) | `SodaxConfig.rpcConfig` (mapped type keyed by `ChainKey` values; chain-family-specific shapes — see [`../breaking-changes/type-system.md`](../breaking-changes/type-system.md) § 5). |
9
- | `SodaxConfig.hubProviderConfig` | Renamed: `SodaxConfig.hubConfig`. |
10
- | `SodaxConfig.configService` (raw `IConfigApi` instance you injected) | Pass via `new Sodax({ configService: <your impl> })` is gone — `ConfigService` is constructed internally. To inject a custom `IConfigApi`, override via `SodaxConfig.backendApi`. |
5
+ ## v2 `SodaxConfig` shape (source of truth)
6
+
7
+ Defined in `@sodax/types` (`packages/types/src/sodax-config/sodax-config.ts`):
8
+
9
+ ```ts
10
+ type SodaxConfig = {
11
+ fee: PartnerFee | undefined; // global partner fee (overridable per-feature)
12
+ chains: Record<SpokeChainKey, SpokeChainConfig>; // per-spoke-chain config (rpcUrl + tx polling + chain-specific shape)
13
+ swaps: SwapsConfig; // supported swap tokens per chain
14
+ moneyMarket: MoneyMarketConfig; // money market service config
15
+ bridge: BridgeConfig; // bridge partner-fee override
16
+ dex: DexConfig; // DEX service config
17
+ hub: HubConfig; // hub-chain (Sonic) provider config
18
+ api: ApiConfig; // backend API endpoint
19
+ solver: SolverConfig; // intent solver endpoint + contracts
20
+ relay: RelayConfig; // intent-relay endpoint
21
+ };
22
+ ```
23
+
24
+ A matching default `sodaxConfig` const is exported from the same module — `new Sodax()` deep-merges your `DeepPartial<SodaxConfig>` over it.
25
+
26
+ ## v1 shape (for reference)
27
+
28
+ ```ts
29
+ // v1 — packages/sdk/src/shared/entities/Sodax.ts
30
+ type SodaxConfig = {
31
+ swaps?: SolverConfigParams; // { intentsContract, solverApiEndpoint, protocolIntentsContract?, partnerFee? }
32
+ moneyMarket?: MoneyMarketConfigParams;
33
+ migration?: MigrationServiceConfig;
34
+ bridge?: BridgeServiceConfig;
35
+ dex?: DexServiceConfig;
36
+ hubProviderConfig?: EvmHubProviderConfig; // { hubRpcUrl, chainConfig }
37
+ relayerApiEndpoint?: HttpUrl; // single URL string
38
+ backendApiConfig?: BackendApiConfig;
39
+ partners?: PartnerServiceConfig;
40
+ sharedConfig?: typeof defaultSharedConfig;
41
+ };
42
+ ```
43
+
44
+ All v1 fields were **optional**. v1 had **no** top-level `rpcConfig` on `SodaxConfig` — RPC URLs were a separate prop accepted by the framework-layer `SodaxProvider` (alongside the `config` prop carrying `SodaxConfig`); the `Sodax` class constructor itself never received `rpcConfig`.
45
+
46
+ ## v1 → v2 field map
47
+
48
+ | v1 location | v2 location | Notes |
49
+ |---|---|---|
50
+ | `SodaxConfig.swaps` (`SolverConfigParams` — `{ intentsContract, solverApiEndpoint, protocolIntentsContract?, partnerFee? }`) | **Split into two:** `SodaxConfig.solver: SolverConfig` (`{ intentsContract, solverApiEndpoint, protocolIntentsContract }`) and `SodaxConfig.swaps: SwapsConfig` (supported tokens per chain — new in v2). | v1 partner-fee inside `SolverConfigParams` moves to the global `SodaxConfig.fee` slot or per-feature configs. |
51
+ | `SodaxConfig.hubProviderConfig` (`EvmHubProviderConfig` — `{ hubRpcUrl, chainConfig }`) | **`SodaxConfig.hub`** (`HubConfig` — full hub addresses + native token + bnUSD + polling + RPC URL). | Field renamed `hubProviderConfig` → `hub`. Shape expanded: v1 just had RPC URL + chain config; v2 ships the full hub-contract address map. |
52
+ | `SodaxConfig.moneyMarket` (`MoneyMarketConfigParams`) | `SodaxConfig.moneyMarket` (`MoneyMarketConfig` — required, shape changed). | Reshape, see `@sodax/types/src/common/common.ts` MoneyMarketConfig. |
53
+ | `SodaxConfig.bridge` (`BridgeServiceConfig`) | `SodaxConfig.bridge` (`BridgeConfig` — `{ partnerFee }`). | Reshape; smaller. |
54
+ | `SodaxConfig.dex` (`DexServiceConfig`) | `SodaxConfig.dex` (`DexConfig`). | Reshape. |
55
+ | `SodaxConfig.relayerApiEndpoint: HttpUrl` (string) | **`SodaxConfig.relay`** (`RelayConfig` — object with relayer URL + chain-id map). | Renamed + reshaped from string to object. |
56
+ | `SodaxConfig.backendApiConfig` (`BackendApiConfig`) | **`SodaxConfig.api`** (`ApiConfig`). | Renamed. |
57
+ | (Separate `rpcConfig` prop on the framework-layer SodaxProvider, NOT a `SodaxConfig` field) | **`SodaxConfig.chains`** (`Record<SpokeChainKey, SpokeChainConfig>`). | v2 absorbs RPC URLs + polling + chain-specific extras into the `SodaxConfig.chains` mapped type. v1's separate `rpcConfig` provider prop is gone. The standalone `RpcConfig` type still ships from `@sodax/types` for utility use (e.g. the demo's `providers.tsx` declares a local `RpcConfig` then maps values into `chains`), but it is not a `SodaxConfig` field. |
58
+ | `SodaxConfig.migration` (`MigrationServiceConfig`) | **Removed.** Migration service runs with hard-coded defaults. | No replacement on `SodaxConfig`. v2 surfaces customization via per-method params on `sodax.migration.*`, not constructor config — see [`../features/icx-bnusd-baln.md`](../features/icx-bnusd-baln.md). |
59
+ | `SodaxConfig.partners` (`PartnerServiceConfig`) | **Removed.** Partner service runs with defaults. | Per-claim partner-fee config now flows via call-level params on `sodax.partners.*` methods. |
60
+ | `SodaxConfig.sharedConfig` (`typeof defaultSharedConfig`) | **Removed.** | Absorbed into `ConfigService` + per-chain `SpokeChainConfig`. Override individual chains via `SodaxConfig.chains[key]`. |
61
+ | (none in v1) | **`SodaxConfig.fee: PartnerFee \| undefined`** (new). | Global partner-fee, applies to all features unless overridden by feature-level config (`bridge.partnerFee`, money market, etc.). |
62
+ | (v1 had no top-level `configService` injection slot on `SodaxConfig` — `ConfigService` was always constructed internally from `backendApiConfig` + `sharedConfig`.) | Same — `ConfigService` is internal. v2 does **not** expose a typed slot to inject a custom `IConfigApi` either. To swap the backend in tests, point `SodaxConfig.api.baseURL` at a mock server. | See Pitfall below. |
11
63
 
12
64
  Migration:
13
65
 
14
66
  ```diff
15
- const sodax = new Sodax({
67
+ - // v1 typical SodaxConfig literal
68
+ - const sodaxConfig = {
69
+ - hubProviderConfig: { hubRpcUrl: 'https://…', chainConfig: getHubChainConfig() },
70
+ - moneyMarket: getMoneyMarketConfig(hubChainId),
16
71
  - swaps: {
17
72
  - intentsContract: '0x…',
18
73
  - solverApiEndpoint: 'https://…',
19
- - supportedTokens: { /* */ },
74
+ - protocolIntentsContract: '0x',
75
+ - partnerFee: { address: '0x…', percentage: 10 },
20
76
  - },
77
+ - relayerApiEndpoint: 'https://relay.example.com',
78
+ - } satisfies SodaxConfig;
79
+ - // RPC URLs were passed as a SEPARATE prop on the framework-layer SodaxProvider
80
+ - // (alongside the sodaxConfig). The Sodax constructor itself never saw rpcConfig.
81
+
82
+ + // v2 — DeepPartial<SodaxConfig> passed directly to new Sodax(...)
83
+ + const sodax = new Sodax({
84
+ + hub: { /* HubConfig — usually omit, default ships full hub addresses */ },
21
85
  + solver: {
22
86
  + intentsContract: '0x…',
23
87
  + solverApiEndpoint: 'https://…',
88
+ + protocolIntentsContract: '0x…',
24
89
  + },
25
90
  + swaps: {
26
91
  + supportedTokens: { /* per-chain table */ },
27
92
  + },
28
- - rpcConfig: { sonic: 'https://…', arbitrum: 'https://…' },
29
- + rpcConfig: {
30
- + [ChainKeys.SONIC_MAINNET]: 'https://…',
31
- + [ChainKeys.ARBITRUM_MAINNET]: 'https://…',
32
- + [ChainKeys.BITCOIN_MAINNET]: { /* BitcoinRpcConfig shape */ },
93
+ + relay: { /* RelayConfig relayer URL + chain-id map */ },
94
+ + fee: { address: '0x…', percentage: 10 }, // global partner fee (moved out of swaps)
95
+ + chains: {
96
+ + [ChainKeys.SONIC_MAINNET]: { rpcUrl: 'https://…' },
97
+ + [ChainKeys.ARBITRUM_MAINNET]: { rpcUrl: 'https://…' },
98
+ + [ChainKeys.BITCOIN_MAINNET]: { /* BitcoinSpokeChainConfig shape */ },
33
99
  + // …
34
100
  + },
35
- - hubProviderConfig: { /* … */ },
36
- + hubConfig: { /* … */ },
37
- });
38
- await sodax.config.initialize();
101
+ + });
102
+ + await sodax.config.initialize();
39
103
  ```
40
104
 
105
+ ## Per-chain `SpokeChainConfig` shape
106
+
107
+ `SodaxConfig.chains` is keyed by `SpokeChainKey`; each entry's value type varies by chain family. The user-overridable surface (`rpcUrl`, polling config, chain-specific extras) is the same set of fields `RpcConfig` covers in v1, but nested inside `SpokeChainConfig` rather than flat. Inspect the type at:
108
+
109
+ - `packages/types/src/chains/chains.ts` — `SpokeChainConfig` discriminated union
110
+ - `packages/types/src/common/common.ts` — `BitcoinRpcConfig`, `StellarRpcConfig`, `InjectiveRpcConfig` (used inside the EVM-non-EVM branches)
111
+
112
+ See [`../breaking-changes/type-system.md`](../breaking-changes/type-system.md) § 5 for the chain-family-specific entry shapes.
113
+
41
114
  ### Pitfall
42
115
 
43
- If you previously injected a custom `ConfigService` for testing (a v1 escape hatch), v2 doesn't accept one at the top level. Inject a custom `IConfigApi` via `SodaxConfig.backendApi.api` instead `ConfigService` consumes it internally on `initialize()`.
116
+ If you previously injected a custom `ConfigService` for testing (a v1 escape hatch), v2 doesn't accept one at the top level and unlike what earlier doc versions claimed, **v2 also doesn't expose a typed slot to inject a custom `IConfigApi`**. The realistic options:
117
+
118
+ - Point `SodaxConfig.api.baseURL` at a local mock backend server.
119
+ - Construct your own `BackendApiService`-compatible object in your app/test bootstrap and swap it in where you control the `Sodax` instance.
120
+
121
+ The `SodaxConfig.api` field is `ApiConfig` (`{ baseURL, timeout, headers }`) — there is no `api.api` sub-field for IConfigApi injection.
122
+
123
+ ### Pitfall — module-scope reads
124
+
125
+ If your code reads hub addresses or default configs **before** the `Sodax` instance exists (module-scope constants), use the re-exported defaults from `@sodax/types` (also flow through `@sodax/sdk` since it re-exports the entire types surface):
126
+
127
+ ```ts
128
+ import { hubConfig, sodaxConfig } from '@sodax/sdk';
129
+
130
+ const HUB_WALLET = hubConfig.addresses.hubWallet; // module-scope OK
131
+ const DEFAULT_RELAY = sodaxConfig.relay; // module-scope OK
132
+ ```
133
+
134
+ `hubConfig` / `sodaxConfig` are the **packaged defaults** — the same values `ConfigService` falls back to if the backend is unreachable. Once you have a `Sodax` instance, prefer `sodax.config.getHubChainConfig()` / `sodax.config.*` so backend-driven updates take effect.
44
135
 
45
136
  ---
46
137
 
@@ -50,3 +141,5 @@ If you previously injected a custom `ConfigService` for testing (a v1 escape hat
50
141
  - [`README.md`](README.md) — migration reference index.
51
142
  - [`../README.md`](../README.md) — migration overview.
52
143
  - [`../checklist.md`](../checklist.md) — top-level migration checklist.
144
+ - [`../breaking-changes/type-system.md`](../breaking-changes/type-system.md) § 5 — per-chain config entry shapes.
145
+ - [`deleted-exports.md`](deleted-exports.md) — `getHubChainConfig()` and other deleted symbols.
package/dist/index.cjs CHANGED
@@ -2794,7 +2794,7 @@ var spokeChainConfig = {
2794
2794
  walletAddress: "",
2795
2795
  pollingConfig: {
2796
2796
  pollingIntervalMs: 750,
2797
- maxTimeoutMs: 6e4
2797
+ maxTimeoutMs: 15e3
2798
2798
  // aligns with blockhash expiry timeout.
2799
2799
  }
2800
2800
  },
@@ -3899,7 +3899,7 @@ function isValidWalletProviderForChainKey(chainKey, walletProvider) {
3899
3899
  }
3900
3900
 
3901
3901
  // ../types/dist/index.js
3902
- var CONFIG_VERSION = 200;
3902
+ var CONFIG_VERSION = 201;
3903
3903
  function isEvmSpokeChainConfig(value) {
3904
3904
  return typeof value === "object" && value !== null && value.chain.type === "EVM" && value.chain.key !== HUB_CHAIN_KEY;
3905
3905
  }
@@ -22876,7 +22876,7 @@ var SolanaSpokeService = class _SolanaSpokeService {
22876
22876
  while (Date.now() < deadline) {
22877
22877
  try {
22878
22878
  const tx = await this.connection.getTransaction(txHash, {
22879
- commitment: "finalized",
22879
+ commitment: "confirmed",
22880
22880
  maxSupportedTransactionVersion: 0
22881
22881
  });
22882
22882
  if (tx) {
@@ -22893,7 +22893,7 @@ var SolanaSpokeService = class _SolanaSpokeService {
22893
22893
  ok: true,
22894
22894
  value: {
22895
22895
  status: "timeout",
22896
- error: new Error(`Timed out after ${maxTimeoutMs}ms waiting for finalized confirmation for ${txHash}`)
22896
+ error: new Error(`Timed out after ${maxTimeoutMs}ms waiting for confirmation for ${txHash}`)
22897
22897
  }
22898
22898
  };
22899
22899
  }