@mixerx/config 0.5.4 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,27 +1,43 @@
1
1
  # @mixerx/config
2
2
 
3
- MixerX protocol config package.
3
+ Validated, immutable MixerX protocol config for Sepolia only.
4
4
 
5
- Supported network ids are exported from `SUPPORTED_NET_IDS`. Pool contracts live
6
- under `instances[chainId]`, and chain-level defaults live under
7
- `networkConfigByNetId[chainId]`.
5
+ Supported network ids are exported from `SUPPORTED_NET_IDS`. Resolve data through
6
+ `getNetworkConfig(chainId)` and `getInstancesForNetId(chainId)` so unsupported
7
+ or prototype-derived keys fail closed. `instances` and `networkConfigByNetId`
8
+ remain exported for current consumers, but every exported object is frozen.
9
+
10
+ This branch deliberately contains no Ethereum mainnet or Tornado Cash catalogue.
11
+ Mainnet must not be enabled until MixerX deployment addresses, blocks and a legal
12
+ review are supplied and tested as a separate network configuration.
8
13
 
9
14
  ## Sepolia status
10
15
 
11
- Version `0.5.4` configures Sepolia (`11155111`) with the `sepolia_v5.4`
12
- generation: its deployed pools, router, registries, pool factories, relayer
16
+ The `sepolia_v5.4` catalogue generation configures Sepolia (`11155111`) with its
17
+ deployed pools, router, registries, pool factories, relayer
13
18
  aggregator, offchain oracle, and FDS token (`DSToken`).
14
19
 
15
- Custom pools that do not map to a fixed denomination use the string key
16
- `custom` in `instanceAddress`, producing pool ids like `eth-custom` or
17
- `fds-custom`.
20
+ The Sepolia ENS registry address is a MixerX deployment rather than the canonical
21
+ Ethereum ENS registry. It is retained because it is the registry used by the
22
+ deployed Phase 5 contracts.
23
+
24
+ The current Phase 5 deployment intentionally uses the FDS contract for both the
25
+ protocol token and wrapped stablecoin roles. Consumers must treat these as roles,
26
+ not as proof that two independent assets exist. A future deployment that separates
27
+ the assets must update both addresses and the contract tests together.
28
+
29
+ The catalogue exposes only the eight fixed-denomination pools currently enabled
30
+ in the Sepolia `InstanceRegistry`. Disabled custom-pool deployments are omitted
31
+ until their on-chain registry metadata and state are valid.
18
32
 
19
- Each currency declares `assetType` as `native` or `erc20`. ERC20 currencies also
20
- declare `tokenAddress`. Consumers derive pool kind from the denomination key:
21
- decimal keys are fixed pools and the `custom` key is a custom pool.
33
+ Each currency declares `assetType` as `native` or `erc20`. ERC20 currencies also
34
+ declare `tokenAddress`.
35
+ Use each currency's `denominations` array when order matters; JavaScript object-key
36
+ ordering is not a protocol ordering guarantee.
22
37
 
23
38
  ## Scripts
24
39
 
25
40
  - `yarn typecheck`
26
41
  - `yarn build`
27
42
  - `yarn check:shape`
43
+ - `yarn test` (build, shape validation and contract/regression tests)
@@ -1,34 +1,2 @@
1
- import type { Address, Instances, Mining, NetworkConfig, RewardSwap, TokenConfig, Torn, TornadoTrees, Vesting, Voucher } from './types.js';
2
- export declare function assertValidConfigShape(input: {
3
- torn: Torn;
4
- miningV2: Mining;
5
- vesting: Vesting;
6
- instances: Instances;
7
- voucher: Voucher;
8
- rewardSwap: RewardSwap;
9
- tornadoTrees: TornadoTrees;
10
- governance: Address;
11
- governanceImpl: Address;
12
- tornadoProxy: Address;
13
- tornadoProxyLight: Address;
14
- rewardVerifier: Address;
15
- treeUpdateVerifier: Address;
16
- withdrawVerifier: Address;
17
- poseidonHasher2: Address;
18
- poseidonHasher3: Address;
19
- feeManager: Address;
20
- tornadoStakingRewards: Address;
21
- relayerRegistry: Address;
22
- tornadoRouter: Address;
23
- instanceRegistry: Address;
24
- deployer: Address;
25
- relayerRegistryProxy: Address;
26
- aggregator: Address;
27
- offchainOracle: Address;
28
- governanceProxy: Address;
29
- tornadoProxyMainnet: Address;
30
- mixerxToken: TokenConfig;
31
- wrappedStablecoin: Address;
32
- networkConfigByNetId: Partial<Record<number, NetworkConfig>>;
33
- }): void;
34
- //# sourceMappingURL=assertions.d.ts.map
1
+ import { type MixerXConfig } from './types.js';
2
+ export declare function assertValidConfigShape(input: unknown): asserts input is MixerXConfig;
@@ -1,236 +1,232 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.assertValidConfigShape = assertValidConfigShape;
4
- const DECIMAL_DENOMINATION_PATTERN = /^\d+(?:\.\d+)?$/;
5
- const isValidAssetType = (value) => {
6
- return value === 'native' || value === 'erc20';
7
- };
8
- const mainnetRequiredContracts = [
9
- 'relayerRegistryAddress',
10
- 'relayerRegistry',
4
+ const types_js_1 = require("./types.js");
5
+ const EVM_ADDRESS_PATTERN = /^0x[0-9a-fA-F]{40}$/u;
6
+ const ZERO_EVM_ADDRESS = '0x0000000000000000000000000000000000000000';
7
+ const DECIMAL_DENOMINATION_PATTERN = /^(?:0|[1-9]\d*)(?:\.\d+)?$/u;
8
+ const TOKEN_SYMBOL_PATTERN = /^[A-Za-z0-9._-]{1,16}$/u;
9
+ const MAX_TOKEN_DECIMALS = 36;
10
+ const CONTRACT_KEYS = [
11
11
  'aggregator',
12
- 'offchainOracleAddress',
13
- 'tornadoRouter',
14
- 'deployer',
15
- 'feeManager',
16
- 'governance',
17
- 'governanceImpl',
18
- 'governanceAddress',
19
- 'instanceRegistry',
20
- 'oldMixerXProxy',
21
- 'poseidonHasher2',
22
- 'poseidonHasher3',
23
- 'rewardSwap',
24
- 'rewardVerifier',
25
- 'tornadoProxy',
26
- 'tornadoProxyLight',
27
- 'tornadoStakingRewards',
28
- 'tornadoTrees',
29
- 'treeUpdateVerifier',
30
- 'voucher',
31
- 'withdrawVerifier',
32
- ];
33
- const sepoliaRequiredContracts = [
34
- 'fds',
35
- 'roles',
36
12
  'config',
37
- 'pauser',
38
- 'feeManager',
39
- 'instanceRegistry',
40
- 'ethPoolFactory',
41
13
  'erc20PoolFactory',
42
- 'relayerRegistryAddress',
43
- 'relayerRegistry',
44
- 'mixerXRouter',
45
- 'verifier',
14
+ 'ensRegistryAddress',
15
+ 'ethPoolFactory',
16
+ 'fds',
17
+ 'feeManager',
46
18
  'hasher',
47
19
  'huffVerifier',
48
- 'aggregator',
20
+ 'instanceRegistry',
21
+ 'mixerXRouter',
49
22
  'noteBackup',
50
- 'ensRegistryAddress',
51
23
  'offchainOracleAddress',
24
+ 'pauser',
25
+ 'relayerRegistry',
26
+ 'relayerRegistryAddress',
27
+ 'roles',
28
+ 'verifier',
52
29
  ];
53
- function assertString(value, key) {
54
- if (typeof value !== 'string' || value.length === 0) {
55
- throw new Error(`Missing ${key}`);
56
- }
57
- }
58
- function assertDeploymentBlock(value, key) {
59
- if (!Number.isInteger(value) || value <= 0) {
60
- throw new Error(`Missing deploymentBlock for ${key}`);
61
- }
62
- }
63
- function assertAddressLike(value, key) {
64
- assertString(value.address, `${key}.address`);
65
- }
66
- function assertToken(value, key) {
67
- assertString(value.address, `${key}.address`);
68
- assertString(value.symbol, `${key}.symbol`);
69
- if (!Number.isFinite(value.decimals) || !Number.isInteger(value.decimals) || value.decimals < 0) {
70
- throw new Error(`Invalid ${key}.decimals`);
71
- }
72
- }
73
- function assertTorn(value) {
74
- assertString(value.address, 'torn.address');
75
- assertString(value.capitalization, 'torn.capitalization');
76
- if (!Number.isFinite(value.pausePeriod) || value.pausePeriod <= 0) {
77
- throw new Error('Invalid torn.pausePeriod');
78
- }
79
- for (const key of ['airdrop', 'miningV2', 'governance', 'team1', 'team2', 'team3', 'team4', 'team5']) {
80
- assertString(value.distribution[key].to, `torn.distribution.${key}.to`);
81
- assertString(value.distribution[key].amount, `torn.distribution.${key}.amount`);
30
+ const CONTRACT_DEPLOYMENT_BLOCK_KEYS = [
31
+ 'erc20PoolFactoryDeploymentBlock',
32
+ 'ensRegistryDeploymentBlock',
33
+ 'ethPoolFactoryDeploymentBlock',
34
+ 'instanceRegistryDeploymentBlock',
35
+ 'relayerRegistryDeploymentBlock',
36
+ ];
37
+ const SUPPORTED_CONTRACT_KEYS = new Set([
38
+ ...CONTRACT_KEYS,
39
+ ...CONTRACT_DEPLOYMENT_BLOCK_KEYS,
40
+ ]);
41
+ function assertRecord(value, label) {
42
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
43
+ throw new Error(`${label} must be an object`);
82
44
  }
83
45
  }
84
- function assertMining(value) {
85
- assertString(value.address, 'miningV2.address');
86
- assertString(value.initialBalance, 'miningV2.initialBalance');
87
- if (!Array.isArray(value.rates) || value.rates.length === 0) {
88
- throw new Error('Invalid miningV2.rates');
46
+ function assertEvmAddress(value, label) {
47
+ if (typeof value !== 'string' || !EVM_ADDRESS_PATTERN.test(value)) {
48
+ throw new Error(`${label} must be a 20-byte EVM address`);
89
49
  }
90
- for (const [index, rate] of value.rates.entries()) {
91
- assertString(rate.instance, `miningV2.rates.${index}.instance`);
92
- assertString(rate.value, `miningV2.rates.${index}.value`);
50
+ if (value.toLowerCase() === ZERO_EVM_ADDRESS) {
51
+ throw new Error(`${label} must not be the zero address`);
93
52
  }
94
53
  }
95
- function assertVesting(value) {
96
- for (const key of ['team1', 'team2', 'team3', 'team4', 'team5', 'governance']) {
97
- const vestingInfo = value[key];
98
- assertString(vestingInfo.address, `vesting.${key}.address`);
99
- if (!Number.isFinite(vestingInfo.cliff) || !Number.isFinite(vestingInfo.duration)) {
100
- throw new Error(`Invalid vesting.${key} schedule`);
101
- }
54
+ function assertPositiveInteger(value, label) {
55
+ if (!Number.isSafeInteger(value) || value <= 0) {
56
+ throw new Error(`${label} must be a positive integer`);
102
57
  }
103
58
  }
104
- function assertVoucher(value) {
105
- assertString(value.address, 'voucher.address');
106
- if (!Number.isFinite(value.duration) || value.duration <= 0) {
107
- throw new Error('Invalid voucher.duration');
59
+ function assertDecimals(value, label) {
60
+ if (!Number.isInteger(value) || value < 0 || value > MAX_TOKEN_DECIMALS) {
61
+ throw new Error(`${label} must be an integer from 0 to ${MAX_TOKEN_DECIMALS}`);
108
62
  }
109
63
  }
110
- function assertRewardSwap(value) {
111
- assertString(value.address, 'rewardSwap.address');
112
- if (!Number.isFinite(value.poolWeight) || value.poolWeight <= 0) {
113
- throw new Error('Invalid rewardSwap.poolWeight');
64
+ function assertTokenSymbol(value, label) {
65
+ if (typeof value !== 'string' || !TOKEN_SYMBOL_PATTERN.test(value)) {
66
+ throw new Error(`${label} must be a 1 to 16 character token symbol`);
114
67
  }
115
68
  }
116
- function assertTornadoTrees(value) {
117
- assertString(value.address, 'tornadoTrees.address');
118
- if (!Number.isInteger(value.levels) || value.levels <= 0) {
119
- throw new Error('Invalid tornadoTrees.levels');
120
- }
69
+ function compareDecimalDenominations(left, right) {
70
+ const [leftInteger = '', leftFraction = ''] = left.split('.');
71
+ const [rightInteger = '', rightFraction = ''] = right.split('.');
72
+ if (leftInteger.length !== rightInteger.length) {
73
+ return leftInteger.length - rightInteger.length;
74
+ }
75
+ if (leftInteger !== rightInteger) {
76
+ return leftInteger < rightInteger ? -1 : 1;
77
+ }
78
+ const fractionLength = Math.max(leftFraction.length, rightFraction.length);
79
+ const normalizedLeftFraction = leftFraction.padEnd(fractionLength, '0');
80
+ const normalizedRightFraction = rightFraction.padEnd(fractionLength, '0');
81
+ if (normalizedLeftFraction === normalizedRightFraction) {
82
+ return 0;
83
+ }
84
+ return normalizedLeftFraction < normalizedRightFraction ? -1 : 1;
121
85
  }
122
- function assertCurrency(network, key, value) {
123
- if (!value.symbol || !Number.isFinite(value.decimals)) {
124
- throw new Error(`Invalid currency metadata for instances.${network}.${key}`);
125
- }
126
- if (!value.instanceAddress || Object.keys(value.instanceAddress).length === 0) {
127
- throw new Error(`Invalid instanceAddress for instances.${network}.${key}`);
128
- }
129
- if (!isValidAssetType(value.assetType)) {
130
- throw new Error(`Invalid assetType for instances.${network}.${key}`);
131
- }
132
- if (value.assetType === 'erc20') {
133
- assertString(value.tokenAddress, `instances.${network}.${key}.tokenAddress`);
134
- }
135
- if (value.assetType === 'native' && 'tokenAddress' in value) {
136
- throw new Error(`Native currency cannot define tokenAddress for instances.${network}.${key}`);
137
- }
138
- for (const [denomination, address] of Object.entries(value.instanceAddress)) {
139
- assertString(address, `instances.${network}.${key}.instanceAddress.${denomination}`);
140
- if (network === '11155111') {
141
- assertDeploymentBlock(value.deploymentBlock?.[denomination], `instances.${network}.${key}.deploymentBlock.${denomination}`);
142
- }
86
+ function assertCurrency(currency, label, poolAddresses) {
87
+ assertRecord(currency, label);
88
+ if (currency.assetType !== 'native' && currency.assetType !== 'erc20') {
89
+ throw new Error(`${label}.assetType must be native or erc20`);
90
+ }
91
+ assertTokenSymbol(currency.symbol, `${label}.symbol`);
92
+ assertDecimals(currency.decimals, `${label}.decimals`);
93
+ if (!Array.isArray(currency.denominations) || currency.denominations.length === 0) {
94
+ throw new Error(`${label}.denominations must be a non-empty array`);
95
+ }
96
+ assertRecord(currency.instanceAddress, `${label}.instanceAddress`);
97
+ assertRecord(currency.deploymentBlock, `${label}.deploymentBlock`);
98
+ const pools = Object.entries(currency.instanceAddress);
99
+ if (pools.length === 0) {
100
+ throw new Error(`${label} must define at least one pool`);
101
+ }
102
+ if (currency.assetType === 'erc20') {
103
+ assertEvmAddress(currency.tokenAddress, `${label}.tokenAddress`);
104
+ }
105
+ else if ('tokenAddress' in currency) {
106
+ throw new Error(`${label} native currency cannot define tokenAddress`);
107
+ }
108
+ const denominationKeys = new Set(pools.map(([denomination]) => denomination));
109
+ if (new Set(currency.denominations).size !== currency.denominations.length ||
110
+ currency.denominations.some((denomination) => !denominationKeys.has(denomination)) ||
111
+ currency.denominations.length !== denominationKeys.size) {
112
+ throw new Error(`${label}.denominations must list each configured pool exactly once`);
113
+ }
114
+ for (const [denomination, address] of pools) {
143
115
  if (denomination !== 'custom' && !DECIMAL_DENOMINATION_PATTERN.test(denomination)) {
144
- throw new Error(`Invalid pool denomination for instances.${network}.${key}.${denomination}`);
116
+ throw new Error(`${label}.${denomination} is not a valid denomination`);
117
+ }
118
+ assertEvmAddress(address, `${label}.instanceAddress.${denomination}`);
119
+ const normalized = address.toLowerCase();
120
+ if (poolAddresses.has(normalized)) {
121
+ throw new Error(`Duplicate pool address ${address}`);
145
122
  }
123
+ poolAddresses.add(normalized);
124
+ assertPositiveInteger(currency.deploymentBlock[denomination], `${label}.deploymentBlock.${denomination}`);
146
125
  }
147
- }
148
- function assertInstances(instances) {
149
- const networks = Object.entries(instances);
150
- if (networks.length === 0) {
151
- throw new Error('Instances config is empty');
152
- }
153
- for (const [network, currencies] of networks) {
154
- const entries = Object.entries(currencies ?? {});
155
- if (entries.length === 0) {
156
- throw new Error(`Network ${network} has no currencies`);
126
+ const expectedOrder = [...denominationKeys].sort((left, right) => {
127
+ if (left === 'custom') {
128
+ return 1;
157
129
  }
158
- for (const [currency, config] of entries) {
159
- assertCurrency(network, currency, config);
130
+ if (right === 'custom') {
131
+ return -1;
160
132
  }
133
+ return compareDecimalDenominations(left, right);
134
+ });
135
+ if (currency.denominations.some((denomination, index) => denomination !== expectedOrder[index])) {
136
+ throw new Error(`${label}.denominations must be in ascending numeric order with custom last`);
161
137
  }
162
138
  }
163
- function assertCompleteNetworkConfig(network, value, requiredContracts) {
164
- if (!value || typeof value !== 'object' || !('contracts' in value) || !value.contracts) {
165
- throw new Error(`Invalid ${network} config: missing contracts`);
166
- }
167
- if (!('tokens' in value) || !value.tokens) {
168
- throw new Error(`Invalid ${network} config: missing tokens`);
169
- }
170
- const { contracts, tokens } = value;
171
- for (const contractKey of requiredContracts) {
172
- assertString(contracts[contractKey], `${network}.contracts.${String(contractKey)}`);
173
- }
174
- if (network === 'sepolia') {
175
- assertDeploymentBlock(contracts.relayerRegistryDeploymentBlock, `${network}.contracts.relayerRegistryDeploymentBlock`);
176
- assertDeploymentBlock(contracts.instanceRegistryDeploymentBlock, `${network}.contracts.instanceRegistryDeploymentBlock`);
177
- assertDeploymentBlock(contracts.ethPoolFactoryDeploymentBlock, `${network}.contracts.ethPoolFactoryDeploymentBlock`);
178
- assertDeploymentBlock(contracts.erc20PoolFactoryDeploymentBlock, `${network}.contracts.erc20PoolFactoryDeploymentBlock`);
179
- assertDeploymentBlock(contracts.ensRegistryDeploymentBlock, `${network}.contracts.ensRegistryDeploymentBlock`);
180
- }
181
- if (!tokens.mixerXTokenAddress ||
182
- !tokens.mixerXTokenSymbol ||
183
- !Number.isFinite(tokens.mixerXTokenDecimals) ||
184
- !tokens.wrappedStablecoinAddress) {
185
- throw new Error(`Invalid ${network} tokens config`);
186
- }
139
+ function assertNetwork(network, poolAddresses) {
140
+ assertRecord(network, `networkConfigByNetId.${types_js_1.SEPOLIA_NET_ID}`);
141
+ assertRecord(network.contracts, `networkConfigByNetId.${types_js_1.SEPOLIA_NET_ID}.contracts`);
142
+ assertRecord(network.tokens, `networkConfigByNetId.${types_js_1.SEPOLIA_NET_ID}.tokens`);
143
+ const unknownContractKey = Object.keys(network.contracts).find((key) => !SUPPORTED_CONTRACT_KEYS.has(key));
144
+ if (unknownContractKey) {
145
+ throw new Error(`sepolia.contracts contains unsupported key ${unknownContractKey}`);
146
+ }
147
+ for (const key of CONTRACT_KEYS) {
148
+ assertEvmAddress(network.contracts[key], `sepolia.contracts.${key}`);
149
+ }
150
+ const contractAddressRoles = new Map();
151
+ for (const key of CONTRACT_KEYS) {
152
+ if (key === 'relayerRegistryAddress') {
153
+ continue;
154
+ }
155
+ const contractAddress = network.contracts[key];
156
+ assertEvmAddress(contractAddress, `sepolia.contracts.${key}`);
157
+ const normalizedAddress = contractAddress.toLowerCase();
158
+ const existingRole = contractAddressRoles.get(normalizedAddress);
159
+ if (existingRole) {
160
+ throw new Error(`Sepolia contract roles ${key} and ${existingRole} must not share an address`);
161
+ }
162
+ if (poolAddresses.has(normalizedAddress)) {
163
+ if (key === 'mixerXRouter') {
164
+ throw new Error('Sepolia router address must not equal a pool address');
165
+ }
166
+ throw new Error(`Sepolia contract ${key} address must not equal a pool address`);
167
+ }
168
+ contractAddressRoles.set(normalizedAddress, key);
169
+ }
170
+ assertPositiveInteger(network.contracts.relayerRegistryDeploymentBlock, 'sepolia.contracts.relayerRegistryDeploymentBlock');
171
+ assertPositiveInteger(network.contracts.ensRegistryDeploymentBlock, 'sepolia.contracts.ensRegistryDeploymentBlock');
172
+ assertPositiveInteger(network.contracts.instanceRegistryDeploymentBlock, 'sepolia.contracts.instanceRegistryDeploymentBlock');
173
+ assertPositiveInteger(network.contracts.ethPoolFactoryDeploymentBlock, 'sepolia.contracts.ethPoolFactoryDeploymentBlock');
174
+ assertPositiveInteger(network.contracts.erc20PoolFactoryDeploymentBlock, 'sepolia.contracts.erc20PoolFactoryDeploymentBlock');
175
+ if (String(network.contracts.relayerRegistry).toLowerCase() !==
176
+ String(network.contracts.relayerRegistryAddress).toLowerCase()) {
177
+ throw new Error('Sepolia relayer registry aliases must resolve to the same address');
178
+ }
179
+ const routerAddress = network.contracts.mixerXRouter;
180
+ assertEvmAddress(routerAddress, 'sepolia.contracts.mixerXRouter');
181
+ assertEvmAddress(network.tokens.mixerXTokenAddress, 'sepolia.tokens.mixerXTokenAddress');
182
+ assertEvmAddress(network.tokens.wrappedStablecoinAddress, 'sepolia.tokens.wrappedStablecoinAddress');
183
+ assertTokenSymbol(network.tokens.mixerXTokenSymbol, 'sepolia.tokens.mixerXTokenSymbol');
184
+ assertDecimals(network.tokens.mixerXTokenDecimals, 'sepolia.tokens.mixerXTokenDecimals');
187
185
  }
188
- function assertNetworkConfig(value) {
189
- const mainnetConfig = value[1];
190
- if (!mainnetConfig) {
191
- throw new Error('Missing networkConfigByNetId.1');
192
- }
193
- const sepoliaConfig = value[11155111];
194
- if (!sepoliaConfig) {
195
- throw new Error('Missing networkConfigByNetId.11155111');
186
+ function assertFdsTokenAliases(network, currencies) {
187
+ const fdsCurrency = currencies.fds;
188
+ assertRecord(fdsCurrency, `instances.${types_js_1.SEPOLIA_NET_ID}.fds`);
189
+ assertEvmAddress(fdsCurrency.tokenAddress, `instances.${types_js_1.SEPOLIA_NET_ID}.fds.tokenAddress`);
190
+ const addresses = [
191
+ network.contracts.fds,
192
+ network.tokens.mixerXTokenAddress,
193
+ network.tokens.wrappedStablecoinAddress,
194
+ fdsCurrency.tokenAddress,
195
+ ];
196
+ if (new Set(addresses.map((address) => address.toLowerCase())).size !== 1) {
197
+ throw new Error('Sepolia FDS address aliases must resolve to the same address');
198
+ }
199
+ if (fdsCurrency.symbol !== network.tokens.mixerXTokenSymbol ||
200
+ fdsCurrency.decimals !== network.tokens.mixerXTokenDecimals) {
201
+ throw new Error('Sepolia FDS symbol and decimals aliases must match');
196
202
  }
197
- assertCompleteNetworkConfig('mainnet', mainnetConfig, mainnetRequiredContracts);
198
- assertCompleteNetworkConfig('sepolia', sepoliaConfig, sepoliaRequiredContracts);
199
203
  }
200
204
  function assertValidConfigShape(input) {
201
- assertTorn(input.torn);
202
- assertMining(input.miningV2);
203
- assertVesting(input.vesting);
204
- assertInstances(input.instances);
205
- assertVoucher(input.voucher);
206
- assertRewardSwap(input.rewardSwap);
207
- assertTornadoTrees(input.tornadoTrees);
208
- for (const [key, value] of [
209
- ['governance', input.governance],
210
- ['governanceImpl', input.governanceImpl],
211
- ['tornadoProxy', input.tornadoProxy],
212
- ['tornadoProxyLight', input.tornadoProxyLight],
213
- ['rewardVerifier', input.rewardVerifier],
214
- ['treeUpdateVerifier', input.treeUpdateVerifier],
215
- ['withdrawVerifier', input.withdrawVerifier],
216
- ['poseidonHasher2', input.poseidonHasher2],
217
- ['poseidonHasher3', input.poseidonHasher3],
218
- ['feeManager', input.feeManager],
219
- ['tornadoStakingRewards', input.tornadoStakingRewards],
220
- ['relayerRegistry', input.relayerRegistry],
221
- ['tornadoRouter', input.tornadoRouter],
222
- ['instanceRegistry', input.instanceRegistry],
223
- ['deployer', input.deployer],
224
- ['relayerRegistryProxy', input.relayerRegistryProxy],
225
- ['aggregator', input.aggregator],
226
- ['offchainOracle', input.offchainOracle],
227
- ['governanceProxy', input.governanceProxy],
228
- ['tornadoProxyMainnet', input.tornadoProxyMainnet],
229
- ['wrappedStablecoin', input.wrappedStablecoin],
230
- ]) {
231
- assertAddressLike(value, key);
232
- }
233
- assertToken(input.mixerxToken, 'mixerxToken');
234
- assertNetworkConfig(input.networkConfigByNetId);
205
+ assertRecord(input, 'config');
206
+ assertRecord(input.instances, 'instances');
207
+ assertRecord(input.networkConfigByNetId, 'networkConfigByNetId');
208
+ const configuredNetIds = Object.keys(input.networkConfigByNetId);
209
+ if (configuredNetIds.length !== types_js_1.SUPPORTED_NET_IDS.length ||
210
+ configuredNetIds[0] !== String(types_js_1.SEPOLIA_NET_ID)) {
211
+ throw new Error(`Only Sepolia network ${types_js_1.SEPOLIA_NET_ID} may be configured`);
212
+ }
213
+ const instanceNetIds = Object.keys(input.instances);
214
+ if (instanceNetIds.length !== types_js_1.SUPPORTED_NET_IDS.length ||
215
+ instanceNetIds[0] !== String(types_js_1.SEPOLIA_NET_ID)) {
216
+ throw new Error(`Only Sepolia network ${types_js_1.SEPOLIA_NET_ID} may define instances`);
217
+ }
218
+ const currencies = input.instances[types_js_1.SEPOLIA_NET_ID];
219
+ assertRecord(currencies, `instances.${types_js_1.SEPOLIA_NET_ID}`);
220
+ const currencyEntries = Object.entries(currencies);
221
+ if (currencyEntries.length === 0) {
222
+ throw new Error(`instances.${types_js_1.SEPOLIA_NET_ID} must define at least one currency`);
223
+ }
224
+ const poolAddresses = new Set();
225
+ for (const [currencyName, currency] of currencyEntries) {
226
+ assertCurrency(currency, `instances.${types_js_1.SEPOLIA_NET_ID}.${currencyName}`, poolAddresses);
227
+ }
228
+ const network = input.networkConfigByNetId[types_js_1.SEPOLIA_NET_ID];
229
+ assertNetwork(network, poolAddresses);
230
+ assertFdsTokenAliases(network, currencies);
235
231
  }
236
232
  //# sourceMappingURL=assertions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"assertions.js","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":";;AA4PA,wDAoEC;AAjTD,MAAM,4BAA4B,GAAG,iBAAiB,CAAC;AAEvD,MAAM,gBAAgB,GAAG,CAAC,KAAc,EAA+B,EAAE;IACvE,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,OAAO,CAAC;AACjD,CAAC,CAAC;AAEF,MAAM,wBAAwB,GAAgD;IAC5E,wBAAwB;IACxB,iBAAiB;IACjB,YAAY;IACZ,uBAAuB;IACvB,eAAe;IACf,UAAU;IACV,YAAY;IACZ,YAAY;IACZ,gBAAgB;IAChB,mBAAmB;IACnB,kBAAkB;IAClB,gBAAgB;IAChB,iBAAiB;IACjB,iBAAiB;IACjB,YAAY;IACZ,gBAAgB;IAChB,cAAc;IACd,mBAAmB;IACnB,uBAAuB;IACvB,cAAc;IACd,oBAAoB;IACpB,SAAS;IACT,kBAAkB;CACnB,CAAC;AAEF,MAAM,wBAAwB,GAAgD;IAC5E,KAAK;IACL,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,YAAY;IACZ,kBAAkB;IAClB,gBAAgB;IAChB,kBAAkB;IAClB,wBAAwB;IACxB,iBAAiB;IACjB,cAAc;IACd,UAAU;IACV,QAAQ;IACR,cAAc;IACd,YAAY;IACZ,YAAY;IACZ,oBAAoB;IACpB,uBAAuB;CACxB,CAAC;AAEF,SAAS,YAAY,CAAC,KAAc,EAAE,GAAW;IAC/C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC;IACpC,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAc,EAAE,GAAW;IACxD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAK,KAAgB,IAAI,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAC;IACxD,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc,EAAE,GAAW;IACpD,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,GAAG,UAAU,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,WAAW,CAAC,KAAkB,EAAE,GAAW;IAClD,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,GAAG,UAAU,CAAC,CAAC;IAC9C,YAAY,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,GAAG,SAAS,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QAChG,MAAM,IAAI,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,KAAW;IAC7B,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAC5C,YAAY,CAAC,KAAK,CAAC,cAAc,EAAE,qBAAqB,CAAC,CAAC;IAC1D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,WAAW,IAAI,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAU,EAAE,CAAC;QAC9G,YAAY,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,qBAAqB,GAAG,KAAK,CAAC,CAAC;QACxE,YAAY,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,qBAAqB,GAAG,SAAS,CAAC,CAAC;IAClF,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;IAChD,YAAY,CAAC,KAAK,CAAC,cAAc,EAAE,yBAAyB,CAAC,CAAC;IAC9D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IACD,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QAClD,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,kBAAkB,KAAK,WAAW,CAAC,CAAC;QAChE,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,kBAAkB,KAAK,QAAQ,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,KAAK,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,CAAU,EAAE,CAAC;QACvF,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,YAAY,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,CAAC,CAAC;QAC5D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClF,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,WAAW,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;IAC/C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAiB;IACzC,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC;IAClD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,UAAU,IAAI,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAmB;IAC7C,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;IACpD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,OAAe,EAAE,GAAW,EAAE,KAAuB;IAC3E,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,2CAA2C,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,eAAe,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9E,MAAM,IAAI,KAAK,CAAC,yCAAyC,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,mCAAmC,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;QAChC,YAAY,CAAC,KAAK,CAAC,YAAY,EAAE,aAAa,OAAO,IAAI,GAAG,eAAe,CAAC,CAAC;IAC/E,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,KAAK,QAAQ,IAAI,cAAc,IAAI,KAAK,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,4DAA4D,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC;IAChG,CAAC;IACD,KAAK,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;QAC5E,YAAY,CAAC,OAAO,EAAE,aAAa,OAAO,IAAI,GAAG,oBAAoB,YAAY,EAAE,CAAC,CAAC;QACrF,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;YAC3B,qBAAqB,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC,YAAY,CAAC,EAAE,aAAa,OAAO,IAAI,GAAG,oBAAoB,YAAY,EAAE,CAAC,CAAC;QAC9H,CAAC;QACD,IAAI,YAAY,KAAK,QAAQ,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;YAClF,MAAM,IAAI,KAAK,CAAC,2CAA2C,OAAO,IAAI,GAAG,IAAI,YAAY,EAAE,CAAC,CAAC;QAC/F,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,SAAoB;IAC3C,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC3C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,QAAQ,EAAE,CAAC;QAC7C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;QACjD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,WAAW,OAAO,oBAAoB,CAAC,CAAC;QAC1D,CAAC;QACD,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACzC,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,2BAA2B,CAClC,OAAe,EACf,KAAoB,EACpB,iBAA8D;IAE9D,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC,WAAW,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QACvF,MAAM,IAAI,KAAK,CAAC,WAAW,OAAO,4BAA4B,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,CAAC,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,WAAW,OAAO,yBAAyB,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACpC,KAAK,MAAM,WAAW,IAAI,iBAAiB,EAAE,CAAC;QAC5C,YAAY,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,GAAG,OAAO,cAAc,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACtF,CAAC;IAED,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,qBAAqB,CAAC,SAAS,CAAC,8BAA8B,EAAE,GAAG,OAAO,2CAA2C,CAAC,CAAC;QACvH,qBAAqB,CACnB,SAAS,CAAC,+BAA+B,EACzC,GAAG,OAAO,4CAA4C,CACvD,CAAC;QACF,qBAAqB,CACnB,SAAS,CAAC,6BAA6B,EACvC,GAAG,OAAO,0CAA0C,CACrD,CAAC;QACF,qBAAqB,CACnB,SAAS,CAAC,+BAA+B,EACzC,GAAG,OAAO,4CAA4C,CACvD,CAAC;QACF,qBAAqB,CAAC,SAAS,CAAC,0BAA0B,EAAE,GAAG,OAAO,uCAAuC,CAAC,CAAC;IACjH,CAAC;IAED,IACE,CAAC,MAAM,CAAC,kBAAkB;QAC1B,CAAC,MAAM,CAAC,iBAAiB;QACzB,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,mBAAmB,CAAC;QAC5C,CAAC,MAAM,CAAC,wBAAwB,EAChC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,WAAW,OAAO,gBAAgB,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,KAA6C;IACxE,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC/B,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,aAAa,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;IACtC,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IAED,2BAA2B,CAAC,SAAS,EAAE,aAAa,EAAE,wBAAwB,CAAC,CAAC;IAChF,2BAA2B,CAAC,SAAS,EAAE,aAAa,EAAE,wBAAwB,CAAC,CAAC;AAClF,CAAC;AAED,SAAgB,sBAAsB,CAAC,KA+BtC;IACC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvB,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC7B,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,eAAe,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACjC,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,gBAAgB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACnC,kBAAkB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAEvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI;QACzB,CAAC,YAAY,EAAE,KAAK,CAAC,UAAU,CAAC;QAChC,CAAC,gBAAgB,EAAE,KAAK,CAAC,cAAc,CAAC;QACxC,CAAC,cAAc,EAAE,KAAK,CAAC,YAAY,CAAC;QACpC,CAAC,mBAAmB,EAAE,KAAK,CAAC,iBAAiB,CAAC;QAC9C,CAAC,gBAAgB,EAAE,KAAK,CAAC,cAAc,CAAC;QACxC,CAAC,oBAAoB,EAAE,KAAK,CAAC,kBAAkB,CAAC;QAChD,CAAC,kBAAkB,EAAE,KAAK,CAAC,gBAAgB,CAAC;QAC5C,CAAC,iBAAiB,EAAE,KAAK,CAAC,eAAe,CAAC;QAC1C,CAAC,iBAAiB,EAAE,KAAK,CAAC,eAAe,CAAC;QAC1C,CAAC,YAAY,EAAE,KAAK,CAAC,UAAU,CAAC;QAChC,CAAC,uBAAuB,EAAE,KAAK,CAAC,qBAAqB,CAAC;QACtD,CAAC,iBAAiB,EAAE,KAAK,CAAC,eAAe,CAAC;QAC1C,CAAC,eAAe,EAAE,KAAK,CAAC,aAAa,CAAC;QACtC,CAAC,kBAAkB,EAAE,KAAK,CAAC,gBAAgB,CAAC;QAC5C,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC;QAC5B,CAAC,sBAAsB,EAAE,KAAK,CAAC,oBAAoB,CAAC;QACpD,CAAC,YAAY,EAAE,KAAK,CAAC,UAAU,CAAC;QAChC,CAAC,gBAAgB,EAAE,KAAK,CAAC,cAAc,CAAC;QACxC,CAAC,iBAAiB,EAAE,KAAK,CAAC,eAAe,CAAC;QAC1C,CAAC,qBAAqB,EAAE,KAAK,CAAC,mBAAmB,CAAC;QAClD,CAAC,mBAAmB,EAAE,KAAK,CAAC,iBAAiB,CAAC;KACtC,EAAE,CAAC;QACX,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,WAAW,CAAC,KAAK,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC9C,mBAAmB,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;AAClD,CAAC"}
1
+ {"version":3,"file":"assertions.js","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n SEPOLIA_NET_ID,\r\n SUPPORTED_NET_IDS,\r\n type InstanceCurrency,\r\n type MixerXConfig,\r\n type NetworkConfig,\r\n type NetworkContractsConfig,\r\n} from './types.js';\r\n\r\nconst EVM_ADDRESS_PATTERN = /^0x[0-9a-fA-F]{40}$/u;\nconst ZERO_EVM_ADDRESS = '0x0000000000000000000000000000000000000000';\nconst DECIMAL_DENOMINATION_PATTERN = /^(?:0|[1-9]\\d*)(?:\\.\\d+)?$/u;\r\nconst TOKEN_SYMBOL_PATTERN = /^[A-Za-z0-9._-]{1,16}$/u;\nconst MAX_TOKEN_DECIMALS = 36;\nconst CONTRACT_KEYS = [\n 'aggregator',\r\n 'config',\r\n 'erc20PoolFactory',\r\n 'ensRegistryAddress',\r\n 'ethPoolFactory',\r\n 'fds',\r\n 'feeManager',\r\n 'hasher',\r\n 'huffVerifier',\r\n 'instanceRegistry',\r\n 'mixerXRouter',\r\n 'noteBackup',\r\n 'offchainOracleAddress',\r\n 'pauser',\r\n 'relayerRegistry',\r\n 'relayerRegistryAddress',\r\n 'roles',\r\n 'verifier',\r\n] as const satisfies readonly (keyof NetworkContractsConfig)[];\nconst CONTRACT_DEPLOYMENT_BLOCK_KEYS = [\n 'erc20PoolFactoryDeploymentBlock',\n 'ensRegistryDeploymentBlock',\n 'ethPoolFactoryDeploymentBlock',\n 'instanceRegistryDeploymentBlock',\n 'relayerRegistryDeploymentBlock',\n] as const satisfies readonly (keyof NetworkContractsConfig)[];\nconst SUPPORTED_CONTRACT_KEYS = new Set<string>([\n ...CONTRACT_KEYS,\n ...CONTRACT_DEPLOYMENT_BLOCK_KEYS,\n]);\n\r\nfunction assertRecord(value: unknown, label: string): asserts value is Record<string, unknown> {\r\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\r\n throw new Error(`${label} must be an object`);\r\n }\r\n}\r\n\r\nfunction assertEvmAddress(value: unknown, label: string): asserts value is `0x${string}` {\n if (typeof value !== 'string' || !EVM_ADDRESS_PATTERN.test(value)) {\n throw new Error(`${label} must be a 20-byte EVM address`);\n }\n if (value.toLowerCase() === ZERO_EVM_ADDRESS) {\n throw new Error(`${label} must not be the zero address`);\n }\n}\n\r\nfunction assertPositiveInteger(value: unknown, label: string): asserts value is number {\r\n if (!Number.isSafeInteger(value) || (value as number) <= 0) {\r\n throw new Error(`${label} must be a positive integer`);\r\n }\r\n}\r\n\r\nfunction assertDecimals(value: unknown, label: string): asserts value is number {\n if (!Number.isInteger(value) || (value as number) < 0 || (value as number) > MAX_TOKEN_DECIMALS) {\n throw new Error(`${label} must be an integer from 0 to ${MAX_TOKEN_DECIMALS}`);\n }\n}\n\nfunction assertTokenSymbol(value: unknown, label: string): asserts value is string {\n if (typeof value !== 'string' || !TOKEN_SYMBOL_PATTERN.test(value)) {\n throw new Error(`${label} must be a 1 to 16 character token symbol`);\n }\n}\n\nfunction compareDecimalDenominations(left: string, right: string): number {\n const [leftInteger = '', leftFraction = ''] = left.split('.');\n const [rightInteger = '', rightFraction = ''] = right.split('.');\n if (leftInteger.length !== rightInteger.length) {\n return leftInteger.length - rightInteger.length;\n }\n if (leftInteger !== rightInteger) {\n return leftInteger < rightInteger ? -1 : 1;\n }\n\n const fractionLength = Math.max(leftFraction.length, rightFraction.length);\n const normalizedLeftFraction = leftFraction.padEnd(fractionLength, '0');\n const normalizedRightFraction = rightFraction.padEnd(fractionLength, '0');\n if (normalizedLeftFraction === normalizedRightFraction) {\n return 0;\n }\n return normalizedLeftFraction < normalizedRightFraction ? -1 : 1;\n}\n\r\nfunction assertCurrency(\r\n currency: unknown,\r\n label: string,\r\n poolAddresses: Set<string>,\r\n): asserts currency is InstanceCurrency {\r\n assertRecord(currency, label);\r\n if (currency.assetType !== 'native' && currency.assetType !== 'erc20') {\r\n throw new Error(`${label}.assetType must be native or erc20`);\r\n }\r\n assertTokenSymbol(currency.symbol, `${label}.symbol`);\n assertDecimals(currency.decimals, `${label}.decimals`);\r\n if (!Array.isArray(currency.denominations) || currency.denominations.length === 0) {\r\n throw new Error(`${label}.denominations must be a non-empty array`);\r\n }\r\n assertRecord(currency.instanceAddress, `${label}.instanceAddress`);\r\n assertRecord(currency.deploymentBlock, `${label}.deploymentBlock`);\r\n const pools = Object.entries(currency.instanceAddress);\r\n if (pools.length === 0) {\r\n throw new Error(`${label} must define at least one pool`);\r\n }\r\n if (currency.assetType === 'erc20') {\r\n assertEvmAddress(currency.tokenAddress, `${label}.tokenAddress`);\r\n } else if ('tokenAddress' in currency) {\r\n throw new Error(`${label} native currency cannot define tokenAddress`);\r\n }\r\n\r\n const denominationKeys = new Set(pools.map(([denomination]) => denomination));\r\n if (\r\n new Set(currency.denominations).size !== currency.denominations.length ||\r\n currency.denominations.some((denomination) => !denominationKeys.has(denomination)) ||\r\n currency.denominations.length !== denominationKeys.size\r\n ) {\r\n throw new Error(`${label}.denominations must list each configured pool exactly once`);\r\n }\r\n\r\n for (const [denomination, address] of pools) {\n if (denomination !== 'custom' && !DECIMAL_DENOMINATION_PATTERN.test(denomination)) {\r\n throw new Error(`${label}.${denomination} is not a valid denomination`);\r\n }\r\n assertEvmAddress(address, `${label}.instanceAddress.${denomination}`);\r\n const normalized = address.toLowerCase();\r\n if (poolAddresses.has(normalized)) {\r\n throw new Error(`Duplicate pool address ${address}`);\r\n }\r\n poolAddresses.add(normalized);\r\n assertPositiveInteger(\n currency.deploymentBlock[denomination],\n `${label}.deploymentBlock.${denomination}`,\n );\n }\n\n const expectedOrder = [...denominationKeys].sort((left, right) => {\n if (left === 'custom') {\n return 1;\n }\n if (right === 'custom') {\n return -1;\n }\n return compareDecimalDenominations(left, right);\n });\n if (currency.denominations.some((denomination, index) => denomination !== expectedOrder[index])) {\n throw new Error(`${label}.denominations must be in ascending numeric order with custom last`);\n }\n}\n\r\nfunction assertNetwork(\n network: unknown,\r\n poolAddresses: Set<string>,\r\n): asserts network is NetworkConfig {\r\n assertRecord(network, `networkConfigByNetId.${SEPOLIA_NET_ID}`);\n assertRecord(network.contracts, `networkConfigByNetId.${SEPOLIA_NET_ID}.contracts`);\n assertRecord(network.tokens, `networkConfigByNetId.${SEPOLIA_NET_ID}.tokens`);\n const unknownContractKey = Object.keys(network.contracts).find(\n (key) => !SUPPORTED_CONTRACT_KEYS.has(key),\n );\n if (unknownContractKey) {\n throw new Error(`sepolia.contracts contains unsupported key ${unknownContractKey}`);\n }\n for (const key of CONTRACT_KEYS) {\n assertEvmAddress(network.contracts[key], `sepolia.contracts.${key}`);\n }\n const contractAddressRoles = new Map<string, string>();\n for (const key of CONTRACT_KEYS) {\n if (key === 'relayerRegistryAddress') {\n continue;\n }\n const contractAddress = network.contracts[key];\n assertEvmAddress(contractAddress, `sepolia.contracts.${key}`);\n const normalizedAddress = contractAddress.toLowerCase();\n const existingRole = contractAddressRoles.get(normalizedAddress);\n if (existingRole) {\n throw new Error(`Sepolia contract roles ${key} and ${existingRole} must not share an address`);\n }\n if (poolAddresses.has(normalizedAddress)) {\n if (key === 'mixerXRouter') {\n throw new Error('Sepolia router address must not equal a pool address');\n }\n throw new Error(`Sepolia contract ${key} address must not equal a pool address`);\n }\n contractAddressRoles.set(normalizedAddress, key);\n }\n assertPositiveInteger(\r\n network.contracts.relayerRegistryDeploymentBlock,\r\n 'sepolia.contracts.relayerRegistryDeploymentBlock',\r\n );\r\n assertPositiveInteger(\r\n network.contracts.ensRegistryDeploymentBlock,\r\n 'sepolia.contracts.ensRegistryDeploymentBlock',\r\n );\r\n assertPositiveInteger(\r\n network.contracts.instanceRegistryDeploymentBlock,\r\n 'sepolia.contracts.instanceRegistryDeploymentBlock',\r\n );\r\n assertPositiveInteger(\r\n network.contracts.ethPoolFactoryDeploymentBlock,\r\n 'sepolia.contracts.ethPoolFactoryDeploymentBlock',\r\n );\r\n assertPositiveInteger(\r\n network.contracts.erc20PoolFactoryDeploymentBlock,\r\n 'sepolia.contracts.erc20PoolFactoryDeploymentBlock',\r\n );\r\n if (\r\n String(network.contracts.relayerRegistry).toLowerCase() !==\r\n String(network.contracts.relayerRegistryAddress).toLowerCase()\r\n ) {\r\n throw new Error('Sepolia relayer registry aliases must resolve to the same address');\r\n }\r\n const routerAddress = network.contracts.mixerXRouter;\r\n assertEvmAddress(routerAddress, 'sepolia.contracts.mixerXRouter');\r\n assertEvmAddress(network.tokens.mixerXTokenAddress, 'sepolia.tokens.mixerXTokenAddress');\r\n assertEvmAddress(\r\n network.tokens.wrappedStablecoinAddress,\r\n 'sepolia.tokens.wrappedStablecoinAddress',\r\n );\r\n assertTokenSymbol(network.tokens.mixerXTokenSymbol, 'sepolia.tokens.mixerXTokenSymbol');\n assertDecimals(network.tokens.mixerXTokenDecimals, 'sepolia.tokens.mixerXTokenDecimals');\n}\n\nfunction assertFdsTokenAliases(\n network: NetworkConfig,\n currencies: Record<string, unknown>,\n): void {\n const fdsCurrency = currencies.fds;\n assertRecord(fdsCurrency, `instances.${SEPOLIA_NET_ID}.fds`);\n assertEvmAddress(fdsCurrency.tokenAddress, `instances.${SEPOLIA_NET_ID}.fds.tokenAddress`);\n\n const addresses = [\n network.contracts.fds,\n network.tokens.mixerXTokenAddress,\n network.tokens.wrappedStablecoinAddress,\n fdsCurrency.tokenAddress,\n ];\n if (new Set(addresses.map((address) => address.toLowerCase())).size !== 1) {\n throw new Error('Sepolia FDS address aliases must resolve to the same address');\n }\n if (\n fdsCurrency.symbol !== network.tokens.mixerXTokenSymbol ||\n fdsCurrency.decimals !== network.tokens.mixerXTokenDecimals\n ) {\n throw new Error('Sepolia FDS symbol and decimals aliases must match');\n }\n}\n\r\nexport function assertValidConfigShape(input: unknown): asserts input is MixerXConfig {\r\n assertRecord(input, 'config');\r\n assertRecord(input.instances, 'instances');\r\n assertRecord(input.networkConfigByNetId, 'networkConfigByNetId');\r\n\r\n const configuredNetIds = Object.keys(input.networkConfigByNetId);\r\n if (\r\n configuredNetIds.length !== SUPPORTED_NET_IDS.length ||\r\n configuredNetIds[0] !== String(SEPOLIA_NET_ID)\r\n ) {\r\n throw new Error(`Only Sepolia network ${SEPOLIA_NET_ID} may be configured`);\r\n }\r\n const instanceNetIds = Object.keys(input.instances);\r\n if (\r\n instanceNetIds.length !== SUPPORTED_NET_IDS.length ||\r\n instanceNetIds[0] !== String(SEPOLIA_NET_ID)\r\n ) {\r\n throw new Error(`Only Sepolia network ${SEPOLIA_NET_ID} may define instances`);\r\n }\r\n const currencies = input.instances[SEPOLIA_NET_ID];\r\n assertRecord(currencies, `instances.${SEPOLIA_NET_ID}`);\r\n const currencyEntries = Object.entries(currencies);\r\n if (currencyEntries.length === 0) {\r\n throw new Error(`instances.${SEPOLIA_NET_ID} must define at least one currency`);\r\n }\r\n const poolAddresses = new Set<string>();\r\n for (const [currencyName, currency] of currencyEntries) {\r\n assertCurrency(currency, `instances.${SEPOLIA_NET_ID}.${currencyName}`, poolAddresses);\r\n }\r\n const network = input.networkConfigByNetId[SEPOLIA_NET_ID];\n assertNetwork(network, poolAddresses);\n assertFdsTokenAliases(network, currencies);\n}\n"]}
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=check-shape.d.ts.map
@@ -1,12 +1,9 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  const assertions_js_1 = require("./assertions.js");
7
- const config_js_1 = __importDefault(require("./config.js"));
4
+ const config_js_1 = require("./config.js");
8
5
  try {
9
- (0, assertions_js_1.assertValidConfigShape)(config_js_1.default);
6
+ (0, assertions_js_1.assertValidConfigShape)(config_js_1.config);
10
7
  }
11
8
  catch (error) {
12
9
  const message = error instanceof Error ? error.message : String(error);
@@ -1 +1 @@
1
- {"version":3,"file":"check-shape.js","sourceRoot":"","sources":["../src/check-shape.ts"],"names":[],"mappings":";;;;;AAAA,mDAAyD;AACzD,4DAAiC;AAEjC,IAAI,CAAC;IACH,IAAA,sCAAsB,EAAC,mBAAM,CAAC,CAAC;AACjC,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,CAAC,KAAK,CAAC,4CAA4C,OAAO,EAAE,CAAC,CAAC;IACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"check-shape.js","sourceRoot":"","sources":["../src/check-shape.ts"],"names":[],"mappings":";;AAAA,mDAAyD;AACzD,2CAAqC;AAErC,IAAI,CAAC;IACH,IAAA,sCAAsB,EAAC,kBAAM,CAAC,CAAC;AACjC,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,CAAC,KAAK,CAAC,4CAA4C,OAAO,EAAE,CAAC,CAAC;IACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC","sourcesContent":["import { assertValidConfigShape } from './assertions.js';\r\nimport { config } from './config.js';\r\n\r\ntry {\r\n assertValidConfigShape(config);\r\n} catch (error) {\r\n const message = error instanceof Error ? error.message : String(error);\r\n console.error(`[mixerx-config] shape validation failed: ${message}`);\r\n process.exit(1);\r\n}\r\n"]}