@paraswap/dex-lib 4.0.13 → 4.0.14
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/.vscode/launch.json +53 -0
- package/.vscode/settings.json +2 -0
- package/.vscode/tasks.json +15 -0
- package/build/abi/{integral/pool.json → inception/inception-ineth-pool.json} +558 -537
- package/build/abi/inception/inception-ratio-feed.json +329 -0
- package/build/abi/inception/inception-vault.json +991 -0
- package/build/abi/uniswap-v3/AlienBaseV3Router.abi.json +52 -0
- package/build/abi/usual-m-smart-m/usualM.abi.json +483 -0
- package/build/abi/{integral/relayer.json → wombat/pool.json} +474 -721
- package/build/dex/aave-v1/aave-v1.d.ts +2 -1
- package/build/dex/aave-v1/aave-v1.js +23 -0
- package/build/dex/aave-v1/aave-v1.js.map +1 -1
- package/build/dex/aave-v2/tokens-avalanche.json +44 -0
- package/build/dex/aave-v2/tokens-mainnet.json +188 -0
- package/build/dex/aave-v2/tokens-polygon.json +44 -0
- package/build/dex/balancer-v3/abi/balancerBatchRouter.d.ts +729 -0
- package/build/dex/balancer-v3/abi/balancerBatchRouter.js +732 -0
- package/build/dex/balancer-v3/abi/balancerBatchRouter.js.map +1 -0
- package/build/dex/balancer-v3/abi/balancerRouter.d.ts +1406 -0
- package/build/dex/balancer-v3/abi/balancerRouter.js +1175 -0
- package/build/dex/balancer-v3/abi/balancerRouter.js.map +1 -0
- package/build/dex/balancer-v3/abi/vaultExtension.V3.d.ts +2081 -0
- package/build/dex/balancer-v3/abi/vaultExtension.V3.js +1851 -0
- package/build/dex/balancer-v3/abi/vaultExtension.V3.js.map +1 -0
- package/build/dex/balancer-v3/balancer-v3-sepolia-pools.d.ts +34 -0
- package/build/dex/balancer-v3/balancer-v3-sepolia-pools.js +406 -0
- package/build/dex/balancer-v3/balancer-v3-sepolia-pools.js.map +1 -0
- package/build/dex/bebop/bebop.js +2 -2
- package/build/dex/bebop/bebop.js.map +1 -1
- package/build/dex/cables/cables.js +7 -3
- package/build/dex/cables/cables.js.map +1 -1
- package/build/dex/curve-v1-factory/curve-v1-factory.js +6 -2
- package/build/dex/curve-v1-factory/curve-v1-factory.js.map +1 -1
- package/build/dex/curve-v1-factory/curve-v1-pool-manager.d.ts +1 -1
- package/build/dex/curve-v1-factory/curve-v1-pool-manager.js +8 -2
- package/build/dex/curve-v1-factory/curve-v1-pool-manager.js.map +1 -1
- package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.d.ts +3 -2
- package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.js +7 -5
- package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.js.map +1 -1
- package/build/dex/curve-v1-factory/state-polling-pools/polling-manager.d.ts +7 -4
- package/build/dex/curve-v1-factory/state-polling-pools/polling-manager.js +23 -11
- package/build/dex/curve-v1-factory/state-polling-pools/polling-manager.js.map +1 -1
- package/build/dex/dexalot/constants.d.ts +2 -2
- package/build/dex/dexalot/constants.js +2 -2
- package/build/dex/dexalot/dexalot.js +8 -4
- package/build/dex/dexalot/dexalot.js.map +1 -1
- package/build/dex/dexalot/rate-fetcher.d.ts +1 -1
- package/build/dex/dexalot/rate-fetcher.js.map +1 -1
- package/build/dex/generic-rfq/rate-fetcher.js +5 -5
- package/build/dex/generic-rfq/rate-fetcher.js.map +1 -1
- package/build/dex/inception/config.d.ts +4 -0
- package/build/dex/inception/config.js +109 -0
- package/build/dex/inception/config.js.map +1 -0
- package/build/dex/inception/inception-event-pool.d.ts +16 -0
- package/build/dex/inception/inception-event-pool.js +49 -0
- package/build/dex/inception/inception-event-pool.js.map +1 -0
- package/build/dex/inception/inception.d.ts +43 -0
- package/build/dex/inception/inception.js +180 -0
- package/build/dex/inception/inception.js.map +1 -0
- package/build/dex/inception/tokens.d.ts +9 -0
- package/build/dex/inception/tokens.js +28 -0
- package/build/dex/inception/tokens.js.map +1 -0
- package/build/dex/inception/types.d.ts +22 -0
- package/build/dex/inception/types.js +3 -0
- package/build/dex/inception/types.js.map +1 -0
- package/build/dex/inception/utils.d.ts +7 -0
- package/build/dex/inception/utils.js +58 -0
- package/build/dex/inception/utils.js.map +1 -0
- package/build/dex/jarvis.d.ts +2 -1
- package/build/dex/jarvis.js +58 -0
- package/build/dex/jarvis.js.map +1 -1
- package/build/dex/maker-psm/scripts/gem.abi.json +136 -0
- package/build/dex/maker-psm/scripts/validate-state.d.ts +0 -0
- package/build/dex/maker-psm/scripts/validate-state.js +185 -0
- package/build/dex/maker-psm/scripts/validate-state.js.map +1 -0
- package/build/dex/maker-psm/scripts/vat.abi.json +243 -0
- package/build/dex/platypus/platypus.d.ts +2 -1
- package/build/dex/platypus/platypus.js +45 -0
- package/build/dex/platypus/platypus.js.map +1 -1
- package/build/dex/solidly-v3/scripts/check-event-pool-event.d.ts +1 -0
- package/build/dex/solidly-v3/scripts/check-event-pool-event.js +53 -0
- package/build/dex/solidly-v3/scripts/check-event-pool-event.js.map +1 -0
- package/build/dex/stable-pool.js +1 -8
- package/build/dex/stable-pool.js.map +1 -1
- package/build/dex/swaap-v1/swaap-v1.d.ts +2 -1
- package/build/dex/swaap-v1/swaap-v1.js +14 -0
- package/build/dex/swaap-v1/swaap-v1.js.map +1 -1
- package/build/dex/swaap-v2/swaap-v2.js +2 -2
- package/build/dex/swaap-v2/swaap-v2.js.map +1 -1
- package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.d.ts +17 -0
- package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.js +64 -0
- package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.js.map +1 -0
- package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.d.ts +17 -0
- package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.js +79 -0
- package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.js.map +1 -0
- package/build/dex/uniswap-v3/uniswap-v3-pricing.d.ts +4 -0
- package/build/dex/uniswap-v3/uniswap-v3-pricing.js +43 -0
- package/build/dex/uniswap-v3/uniswap-v3-pricing.js.map +1 -0
- package/build/dex/uniswap-v3/uniswap-v3-worker.d.ts +1 -0
- package/build/dex/uniswap-v3/uniswap-v3-worker.js +10 -0
- package/build/dex/uniswap-v3/uniswap-v3-worker.js.map +1 -0
- package/build/dex/usual/usual-m-smart-m.d.ts +17 -0
- package/build/dex/usual/usual-m-smart-m.js +50 -0
- package/build/dex/usual/usual-m-smart-m.js.map +1 -0
- package/build/dex/usual-m-smart-m/config.d.ts +3 -0
- package/build/dex/usual-m-smart-m/config.js +13 -0
- package/build/dex/usual-m-smart-m/config.js.map +1 -0
- package/build/dex/usual-m-smart-m/types.d.ts +7 -0
- package/build/dex/usual-m-smart-m/types.js +3 -0
- package/build/dex/usual-m-smart-m/types.js.map +1 -0
- package/build/dex/usual-m-smart-m/usual-m-smart-m.d.ts +35 -0
- package/build/dex/usual-m-smart-m/usual-m-smart-m.js +161 -0
- package/build/dex/usual-m-smart-m/usual-m-smart-m.js.map +1 -0
- package/build/dex/usual-m-usd0/config.d.ts +3 -0
- package/build/dex/usual-m-usd0/config.js +14 -0
- package/build/dex/usual-m-usd0/config.js.map +1 -0
- package/build/dex/usual-m-usd0/types.d.ts +8 -0
- package/build/dex/usual-m-usd0/types.js +3 -0
- package/build/dex/usual-m-usd0/types.js.map +1 -0
- package/build/dex/usual-m-usd0/usual-m-usd0.d.ts +35 -0
- package/build/dex/usual-m-usd0/usual-m-usd0.js +159 -0
- package/build/dex/usual-m-usd0/usual-m-usd0.js.map +1 -0
- package/build/dex/zerox/index.d.ts +4 -26
- package/build/dex/zerox/index.js +50 -42
- package/build/dex/zerox/index.js.map +1 -1
- package/build/dex/zerox/types.d.ts +29 -0
- package/build/dex/zerox/types.js +8 -1
- package/build/dex/zerox/types.js.map +1 -1
- package/build/dex-helper/dummy-dex-helper.js +10 -0
- package/build/dex-helper/dummy-dex-helper.js.map +1 -1
- package/build/dex-helper/icache.d.ts +3 -0
- package/build/lib/pub-sub.d.ts +51 -0
- package/build/lib/pub-sub.js +199 -0
- package/build/lib/pub-sub.js.map +1 -0
- package/package.json +1 -1
- package/src/abi/fluid-dex/fluid-dex.abi.json +2 -4
- package/src/dex/bebop/bebop.ts +4 -2
- package/src/dex/cables/cables.ts +9 -3
- package/src/dex/curve-v1-factory/curve-v1-factory.ts +5 -1
- package/src/dex/curve-v1-factory/curve-v1-pool-manager.ts +17 -1
- package/src/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.ts +4 -4
- package/src/dex/curve-v1-factory/state-polling-pools/polling-manager.ts +32 -21
- package/src/dex/dexalot/constants.ts +2 -2
- package/src/dex/dexalot/dexalot.ts +11 -4
- package/src/dex/dexalot/rate-fetcher.ts +6 -6
- package/src/dex/generic-rfq/rate-fetcher.ts +10 -5
- package/src/dex/swaap-v2/swaap-v2.ts +4 -2
- package/src/dex-helper/dummy-dex-helper.ts +21 -0
- package/src/dex-helper/icache.ts +6 -0
- package/src/lib/pub-sub.ts +252 -0
- package/.idea/aws.xml +0 -17
- package/.idea/codeStyles/Project.xml +0 -19
- package/.idea/codeStyles/codeStyleConfig.xml +0 -5
- package/.idea/misc.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/paraswap-dex-lib.iml +0 -9
- package/.idea/prettier.xml +0 -7
- package/.idea/vcs.xml +0 -6
- package/build/abi/integral/factory.json +0 -333
- package/build/abi/integral/oracle.json +0 -501
- package/build/dex/fluid-dex/fluid-dex-generate-pool.d.ts +0 -49
- package/build/dex/fluid-dex/fluid-dex-generate-pool.js +0 -104
- package/build/dex/fluid-dex/fluid-dex-generate-pool.js.map +0 -1
- package/build/dex/integral/config.d.ts +0 -4
- package/build/dex/integral/config.js +0 -20
- package/build/dex/integral/config.js.map +0 -1
- package/build/dex/integral/context.d.ts +0 -40
- package/build/dex/integral/context.js +0 -158
- package/build/dex/integral/context.js.map +0 -1
- package/build/dex/integral/integral-factory.d.ts +0 -24
- package/build/dex/integral/integral-factory.js +0 -95
- package/build/dex/integral/integral-factory.js.map +0 -1
- package/build/dex/integral/integral-pool.d.ts +0 -50
- package/build/dex/integral/integral-pool.js +0 -149
- package/build/dex/integral/integral-pool.js.map +0 -1
- package/build/dex/integral/integral-pricing.d.ts +0 -18
- package/build/dex/integral/integral-pricing.js +0 -114
- package/build/dex/integral/integral-pricing.js.map +0 -1
- package/build/dex/integral/integral-relayer.d.ts +0 -42
- package/build/dex/integral/integral-relayer.js +0 -192
- package/build/dex/integral/integral-relayer.js.map +0 -1
- package/build/dex/integral/integral-token.d.ts +0 -27
- package/build/dex/integral/integral-token.js +0 -59
- package/build/dex/integral/integral-token.js.map +0 -1
- package/build/dex/integral/integral.d.ts +0 -41
- package/build/dex/integral/integral.js +0 -376
- package/build/dex/integral/integral.js.map +0 -1
- package/build/dex/integral/types.d.ts +0 -85
- package/build/dex/integral/types.js +0 -9
- package/build/dex/integral/types.js.map +0 -1
- package/build/dex/integral/utils-e2e.d.ts +0 -9
- package/build/dex/integral/utils-e2e.js +0 -131
- package/build/dex/integral/utils-e2e.js.map +0 -1
- package/build/dex/integral/utils.d.ts +0 -17
- package/build/dex/integral/utils.js +0 -94
- package/build/dex/integral/utils.js.map +0 -1
- package/build/dex/trader-joe-v2.1/optimizer.d.ts +0 -2
- package/build/dex/trader-joe-v2.1/optimizer.js +0 -47
- package/build/dex/trader-joe-v2.1/optimizer.js.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Logger } from 'log4js';
|
|
2
|
-
import { Network } from '../../../constants';
|
|
3
2
|
import { IDexHelper } from '../../../dex-helper';
|
|
4
3
|
import { Utils, _require } from '../../../utils';
|
|
5
4
|
import { PoolState } from '../types';
|
|
6
5
|
import { MulticallReturnedTypes, PoolPollingBase } from './pool-polling-base';
|
|
6
|
+
import { ExpHashPubSub } from '../../../lib/pub-sub';
|
|
7
7
|
|
|
8
8
|
/*
|
|
9
9
|
* Since we are updating all pools state at once, I need some generalized iterator without state,
|
|
@@ -11,7 +11,17 @@ import { MulticallReturnedTypes, PoolPollingBase } from './pool-polling-base';
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
export class StatePollingManager {
|
|
14
|
-
|
|
14
|
+
private pubSub: ExpHashPubSub;
|
|
15
|
+
|
|
16
|
+
constructor(dexHelper: IDexHelper, cacheKey: string, ttl: number) {
|
|
17
|
+
this.pubSub = new ExpHashPubSub(dexHelper, cacheKey, ttl);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
subscribe() {
|
|
21
|
+
this.pubSub.subscribe();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async fetchAndSetStatesFromRPC(
|
|
15
25
|
dexHelper: IDexHelper,
|
|
16
26
|
pools: PoolPollingBase[],
|
|
17
27
|
blockNumber?: number,
|
|
@@ -94,7 +104,7 @@ export class StatePollingManager {
|
|
|
94
104
|
return newStates;
|
|
95
105
|
}
|
|
96
106
|
|
|
97
|
-
|
|
107
|
+
async masterUpdatePoolsInBatch(
|
|
98
108
|
logger: Logger,
|
|
99
109
|
dexHelper: IDexHelper,
|
|
100
110
|
pools: PoolPollingBase[],
|
|
@@ -102,7 +112,7 @@ export class StatePollingManager {
|
|
|
102
112
|
) {
|
|
103
113
|
const dexKey = pools.length > 0 ? pools[0].dexKey : 'CurveV1Factory';
|
|
104
114
|
try {
|
|
105
|
-
const newStates = await
|
|
115
|
+
const newStates = await this.fetchAndSetStatesFromRPC(
|
|
106
116
|
dexHelper,
|
|
107
117
|
pools,
|
|
108
118
|
blockNumber,
|
|
@@ -113,6 +123,17 @@ export class StatePollingManager {
|
|
|
113
123
|
{ poolLength: pools.length, newStatesLength: newStates.length },
|
|
114
124
|
'newStates.length === pools.length',
|
|
115
125
|
);
|
|
126
|
+
|
|
127
|
+
const dataToPublish: Record<string, PoolState | null> = newStates.reduce(
|
|
128
|
+
(acc, state, i) => {
|
|
129
|
+
acc[pools[i].poolIdentifier] = state;
|
|
130
|
+
return acc;
|
|
131
|
+
},
|
|
132
|
+
{} as Record<string, PoolState | null>,
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
this.pubSub.publish(dataToPublish);
|
|
136
|
+
|
|
116
137
|
await Promise.all(
|
|
117
138
|
pools.map(async (p, i) => {
|
|
118
139
|
if (newStates[i] !== null) {
|
|
@@ -143,7 +164,7 @@ export class StatePollingManager {
|
|
|
143
164
|
}
|
|
144
165
|
}
|
|
145
166
|
|
|
146
|
-
|
|
167
|
+
async slaveUpdatePoolsInBatch(
|
|
147
168
|
logger: Logger,
|
|
148
169
|
dexHelper: IDexHelper,
|
|
149
170
|
pools: PoolPollingBase[],
|
|
@@ -155,15 +176,10 @@ export class StatePollingManager {
|
|
|
155
176
|
await Promise.all(
|
|
156
177
|
pools.map(async p => {
|
|
157
178
|
try {
|
|
158
|
-
const
|
|
159
|
-
p.cacheStateKey,
|
|
179
|
+
const parsedState = await this.pubSub.getAndCache<PoolState>(
|
|
160
180
|
p.poolIdentifier,
|
|
161
181
|
);
|
|
162
|
-
if (
|
|
163
|
-
const parsedState = Utils.Parse(
|
|
164
|
-
unparsedStateFromCache,
|
|
165
|
-
) as PoolState;
|
|
166
|
-
|
|
182
|
+
if (parsedState !== null) {
|
|
167
183
|
if (p.isStateUpToDate(parsedState)) {
|
|
168
184
|
p.setState(parsedState);
|
|
169
185
|
return;
|
|
@@ -197,7 +213,7 @@ export class StatePollingManager {
|
|
|
197
213
|
}. Falling back to RPC`,
|
|
198
214
|
);
|
|
199
215
|
|
|
200
|
-
await
|
|
216
|
+
await this.fetchAndSetStatesFromRPC(
|
|
201
217
|
dexHelper,
|
|
202
218
|
poolsForRPCUpdate,
|
|
203
219
|
blockNumber,
|
|
@@ -217,7 +233,7 @@ export class StatePollingManager {
|
|
|
217
233
|
}
|
|
218
234
|
}
|
|
219
235
|
|
|
220
|
-
|
|
236
|
+
async updatePoolsInBatch(
|
|
221
237
|
logger: Logger,
|
|
222
238
|
dexHelper: IDexHelper,
|
|
223
239
|
pools: PoolPollingBase[],
|
|
@@ -233,14 +249,9 @@ export class StatePollingManager {
|
|
|
233
249
|
}
|
|
234
250
|
|
|
235
251
|
if (dexHelper.config.isSlave) {
|
|
236
|
-
await
|
|
237
|
-
logger,
|
|
238
|
-
dexHelper,
|
|
239
|
-
pools,
|
|
240
|
-
blockNumber,
|
|
241
|
-
);
|
|
252
|
+
await this.slaveUpdatePoolsInBatch(logger, dexHelper, pools, blockNumber);
|
|
242
253
|
} else {
|
|
243
|
-
await
|
|
254
|
+
await this.masterUpdatePoolsInBatch(
|
|
244
255
|
logger,
|
|
245
256
|
dexHelper,
|
|
246
257
|
pools,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import BigNumber from 'bignumber.js';
|
|
2
2
|
|
|
3
|
-
export const DEXALOT_PRICES_CACHES_TTL_S =
|
|
3
|
+
export const DEXALOT_PRICES_CACHES_TTL_S = 5;
|
|
4
4
|
|
|
5
5
|
export const DEXALOT_PAIRS_CACHES_TTL_S = 21 * 60; // 21 mins
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@ export const DEXALOT_TOKENS_CACHES_TTL_S = 21 * 60; // 21 mins
|
|
|
8
8
|
|
|
9
9
|
export const DEXALOT_BLACKLIST_CACHES_TTL_S = 180 * 60; // 3 hours
|
|
10
10
|
|
|
11
|
-
export const DEXALOT_API_PRICES_POLLING_INTERVAL_MS =
|
|
11
|
+
export const DEXALOT_API_PRICES_POLLING_INTERVAL_MS = 2000;
|
|
12
12
|
|
|
13
13
|
export const DEXALOT_API_PAIRS_POLLING_INTERVAL_MS = 1000 * 60 * 10; // 10 mins
|
|
14
14
|
|
|
@@ -239,10 +239,14 @@ export class Dexalot extends SimpleExchange implements IDex<DexalotData> {
|
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
async getCachedPairs(): Promise<PairDataMap | null> {
|
|
242
|
-
const cachedPairs = await this.dexHelper.cache.
|
|
242
|
+
const cachedPairs = await this.dexHelper.cache.getAndCacheLocally(
|
|
243
243
|
this.dexKey,
|
|
244
244
|
this.network,
|
|
245
245
|
this.pairsCacheKey,
|
|
246
|
+
// as local cache just uses passed ttl (instead of getting actual ttl from cache)
|
|
247
|
+
// pass shorter interval to avoid getting stale data
|
|
248
|
+
// (same logic is used in other places)
|
|
249
|
+
DEXALOT_API_PAIRS_POLLING_INTERVAL_MS / 1000,
|
|
246
250
|
);
|
|
247
251
|
|
|
248
252
|
if (cachedPairs) {
|
|
@@ -253,10 +257,11 @@ export class Dexalot extends SimpleExchange implements IDex<DexalotData> {
|
|
|
253
257
|
}
|
|
254
258
|
|
|
255
259
|
async getCachedPrices(): Promise<PriceDataMap | null> {
|
|
256
|
-
const cachedPrices = await this.dexHelper.cache.
|
|
260
|
+
const cachedPrices = await this.dexHelper.cache.getAndCacheLocally(
|
|
257
261
|
this.dexKey,
|
|
258
262
|
this.network,
|
|
259
263
|
this.pricesCacheKey,
|
|
264
|
+
DEXALOT_API_PRICES_POLLING_INTERVAL_MS / 1000,
|
|
260
265
|
);
|
|
261
266
|
|
|
262
267
|
if (cachedPrices) {
|
|
@@ -267,10 +272,11 @@ export class Dexalot extends SimpleExchange implements IDex<DexalotData> {
|
|
|
267
272
|
}
|
|
268
273
|
|
|
269
274
|
async getCachedTokensAddr(): Promise<TokenAddrDataMap | null> {
|
|
270
|
-
const cachedTokensAddr = await this.dexHelper.cache.
|
|
275
|
+
const cachedTokensAddr = await this.dexHelper.cache.getAndCacheLocally(
|
|
271
276
|
this.dexKey,
|
|
272
277
|
this.network,
|
|
273
278
|
this.tokensAddrCacheKey,
|
|
279
|
+
DEXALOT_API_PAIRS_POLLING_INTERVAL_MS / 1000,
|
|
274
280
|
);
|
|
275
281
|
|
|
276
282
|
if (cachedTokensAddr) {
|
|
@@ -281,10 +287,11 @@ export class Dexalot extends SimpleExchange implements IDex<DexalotData> {
|
|
|
281
287
|
}
|
|
282
288
|
|
|
283
289
|
async getCachedTokens(): Promise<TokenDataMap | null> {
|
|
284
|
-
const cachedTokens = await this.dexHelper.cache.
|
|
290
|
+
const cachedTokens = await this.dexHelper.cache.getAndCacheLocally(
|
|
285
291
|
this.dexKey,
|
|
286
292
|
this.network,
|
|
287
293
|
this.tokensCacheKey,
|
|
294
|
+
DEXALOT_API_PAIRS_POLLING_INTERVAL_MS / 1000,
|
|
288
295
|
);
|
|
289
296
|
|
|
290
297
|
if (cachedTokens) {
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
+
import { Network } from '../../constants';
|
|
1
2
|
import { IDexHelper } from '../../dex-helper';
|
|
2
3
|
import { Fetcher } from '../../lib/fetcher/fetcher';
|
|
3
4
|
import { validateAndCast } from '../../lib/validators';
|
|
4
5
|
import { Logger, Token } from '../../types';
|
|
5
6
|
import {
|
|
6
|
-
|
|
7
|
+
DexalotBlacklistResponse,
|
|
7
8
|
DexalotPairsResponse,
|
|
8
|
-
PairDataMap,
|
|
9
9
|
DexalotPricesResponse,
|
|
10
|
+
DexalotRateFetcherConfig,
|
|
11
|
+
PairDataMap,
|
|
10
12
|
PriceDataMap,
|
|
11
|
-
DexalotBlacklistResponse,
|
|
12
13
|
} from './types';
|
|
13
14
|
import {
|
|
14
|
-
pricesResponseValidator,
|
|
15
|
-
pairsResponseValidator,
|
|
16
15
|
blacklistResponseValidator,
|
|
16
|
+
pairsResponseValidator,
|
|
17
|
+
pricesResponseValidator,
|
|
17
18
|
} from './validators';
|
|
18
|
-
import { Network } from '../../constants';
|
|
19
19
|
|
|
20
20
|
export class RateFetcher {
|
|
21
21
|
private pairsFetcher: Fetcher<DexalotPairsResponse>;
|
|
@@ -322,10 +322,11 @@ export class RateFetcher {
|
|
|
322
322
|
}
|
|
323
323
|
|
|
324
324
|
public async getAvailablePairs(): Promise<string[]> {
|
|
325
|
-
const pairs = await this.dexHelper.cache.
|
|
325
|
+
const pairs = await this.dexHelper.cache.getAndCacheLocally(
|
|
326
326
|
this.dexKey,
|
|
327
327
|
this.dexHelper.config.data.network,
|
|
328
328
|
`pairs`,
|
|
329
|
+
this.config.rateConfig.dataTTLS,
|
|
329
330
|
);
|
|
330
331
|
|
|
331
332
|
if (!pairs) {
|
|
@@ -344,32 +345,36 @@ export class RateFetcher {
|
|
|
344
345
|
|
|
345
346
|
let pricesAsString: string | null = null;
|
|
346
347
|
if (side === SwapSide.SELL) {
|
|
347
|
-
pricesAsString = await this.dexHelper.cache.
|
|
348
|
+
pricesAsString = await this.dexHelper.cache.getAndCacheLocally(
|
|
348
349
|
this.dexKey,
|
|
349
350
|
this.dexHelper.config.data.network,
|
|
350
351
|
`${srcToken.address}_${destToken.address}_bids`,
|
|
352
|
+
this.config.rateConfig.dataTTLS,
|
|
351
353
|
);
|
|
352
354
|
|
|
353
355
|
if (!pricesAsString) {
|
|
354
|
-
pricesAsString = await this.dexHelper.cache.
|
|
356
|
+
pricesAsString = await this.dexHelper.cache.getAndCacheLocally(
|
|
355
357
|
this.dexKey,
|
|
356
358
|
this.dexHelper.config.data.network,
|
|
357
359
|
`${destToken.address}_${srcToken.address}_asks`,
|
|
360
|
+
this.config.rateConfig.dataTTLS,
|
|
358
361
|
);
|
|
359
362
|
reversed = true;
|
|
360
363
|
}
|
|
361
364
|
} else {
|
|
362
|
-
pricesAsString = await this.dexHelper.cache.
|
|
365
|
+
pricesAsString = await this.dexHelper.cache.getAndCacheLocally(
|
|
363
366
|
this.dexKey,
|
|
364
367
|
this.dexHelper.config.data.network,
|
|
365
368
|
`${destToken.address}_${srcToken.address}_asks`,
|
|
369
|
+
this.config.rateConfig.dataTTLS,
|
|
366
370
|
);
|
|
367
371
|
|
|
368
372
|
if (!pricesAsString) {
|
|
369
|
-
pricesAsString = await this.dexHelper.cache.
|
|
373
|
+
pricesAsString = await this.dexHelper.cache.getAndCacheLocally(
|
|
370
374
|
this.dexKey,
|
|
371
375
|
this.dexHelper.config.data.network,
|
|
372
376
|
`${srcToken.address}_${destToken.address}_bids`,
|
|
377
|
+
this.config.rateConfig.dataTTLS,
|
|
373
378
|
);
|
|
374
379
|
reversed = true;
|
|
375
380
|
}
|
|
@@ -278,10 +278,11 @@ export class SwaapV2 extends SimpleExchange implements IDex<SwaapV2Data> {
|
|
|
278
278
|
}
|
|
279
279
|
|
|
280
280
|
async getCachedTokens(): Promise<TokensMap | null> {
|
|
281
|
-
const cachedTokens = await this.dexHelper.cache.
|
|
281
|
+
const cachedTokens = await this.dexHelper.cache.getAndCacheLocally(
|
|
282
282
|
this.dexKey,
|
|
283
283
|
this.network,
|
|
284
284
|
SWAAP_TOKENS_CACHE_KEY,
|
|
285
|
+
SWAAP_RFQ_API_TOKENS_POLLING_INTERVAL_MS / 1000,
|
|
285
286
|
);
|
|
286
287
|
|
|
287
288
|
if (cachedTokens) {
|
|
@@ -292,10 +293,11 @@ export class SwaapV2 extends SimpleExchange implements IDex<SwaapV2Data> {
|
|
|
292
293
|
}
|
|
293
294
|
|
|
294
295
|
async getCachedLevels(): Promise<Record<string, SwaapV2PriceLevels> | null> {
|
|
295
|
-
const cachedLevels = await this.dexHelper.cache.
|
|
296
|
+
const cachedLevels = await this.dexHelper.cache.getAndCacheLocally(
|
|
296
297
|
this.dexKey,
|
|
297
298
|
this.network,
|
|
298
299
|
SWAAP_PRICES_CACHE_KEY,
|
|
300
|
+
SWAAP_RFQ_API_PRICES_POLLING_INTERVAL_MS / 1000,
|
|
299
301
|
);
|
|
300
302
|
|
|
301
303
|
if (cachedLevels) {
|
|
@@ -43,6 +43,23 @@ class DummyCache implements ICache {
|
|
|
43
43
|
return null;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
async keys(
|
|
47
|
+
dexKey: string,
|
|
48
|
+
network: number,
|
|
49
|
+
cacheKey: string,
|
|
50
|
+
): Promise<string[]> {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async ttl(
|
|
55
|
+
dexKey: string,
|
|
56
|
+
network: number,
|
|
57
|
+
cacheKey: string,
|
|
58
|
+
): Promise<number> {
|
|
59
|
+
const key = `${network}_${dexKey}_${cacheKey}`.toLowerCase();
|
|
60
|
+
return this.storage[key] ? 1 : -1;
|
|
61
|
+
}
|
|
62
|
+
|
|
46
63
|
async rawget(key: string): Promise<string | null> {
|
|
47
64
|
return this.storage[key] ? this.storage[key] : null;
|
|
48
65
|
return null;
|
|
@@ -139,6 +156,10 @@ class DummyCache implements ICache {
|
|
|
139
156
|
return set.has(key);
|
|
140
157
|
}
|
|
141
158
|
|
|
159
|
+
async smembers(setKey: string): Promise<string[]> {
|
|
160
|
+
return Array.from(this.setMap[setKey] ?? []);
|
|
161
|
+
}
|
|
162
|
+
|
|
142
163
|
async hset(mapKey: string, key: string, value: string): Promise<void> {
|
|
143
164
|
if (!this.hashStorage[mapKey]) this.hashStorage[mapKey] = {};
|
|
144
165
|
this.hashStorage[mapKey][key] = value;
|
package/src/dex-helper/icache.ts
CHANGED
|
@@ -5,6 +5,10 @@ export interface ICache {
|
|
|
5
5
|
cacheKey: string,
|
|
6
6
|
): Promise<string | null>;
|
|
7
7
|
|
|
8
|
+
ttl(dexKey: string, network: number, cacheKey: string): Promise<number>;
|
|
9
|
+
|
|
10
|
+
keys(dexKey: string, network: number, cacheKey: string): Promise<string[]>;
|
|
11
|
+
|
|
8
12
|
rawget(key: string): Promise<string | null>;
|
|
9
13
|
|
|
10
14
|
rawset(key: string, value: string, ttl: number): Promise<string | null>;
|
|
@@ -52,6 +56,8 @@ export interface ICache {
|
|
|
52
56
|
|
|
53
57
|
sismember(setKey: string, key: string): Promise<boolean>;
|
|
54
58
|
|
|
59
|
+
smembers(setKey: string): Promise<string[]>;
|
|
60
|
+
|
|
55
61
|
hset(mapKey: string, key: string, value: string): Promise<void>;
|
|
56
62
|
|
|
57
63
|
hdel(mapKey: string, keys: string[]): Promise<number>;
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import NodeCache from 'node-cache';
|
|
2
|
+
import { Network } from '../constants';
|
|
3
|
+
import { IDexHelper } from '../dex-helper';
|
|
4
|
+
import { Logger } from '../types';
|
|
5
|
+
import { Utils } from '../utils';
|
|
6
|
+
|
|
7
|
+
type KeyValuePubSubMsg = {
|
|
8
|
+
expiresAt: number;
|
|
9
|
+
data: Record<string, unknown>;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
type SetPubSubMsg = string[];
|
|
13
|
+
|
|
14
|
+
export class ExpStringPubSub {
|
|
15
|
+
channel: string;
|
|
16
|
+
network: Network;
|
|
17
|
+
localCache: NodeCache = new NodeCache();
|
|
18
|
+
|
|
19
|
+
logger: Logger;
|
|
20
|
+
|
|
21
|
+
constructor(
|
|
22
|
+
private dexHelper: IDexHelper,
|
|
23
|
+
private dexKey: string,
|
|
24
|
+
channel: string,
|
|
25
|
+
private defaultValue?: any,
|
|
26
|
+
private defaultTTL?: number,
|
|
27
|
+
) {
|
|
28
|
+
this.network = this.dexHelper.config.data.network;
|
|
29
|
+
this.channel = `${this.network}_${this.dexKey}_${channel}`;
|
|
30
|
+
|
|
31
|
+
this.logger = this.dexHelper.getLogger(`ExpKeyValuePubSub_${this.channel}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
subscribe() {
|
|
35
|
+
this.logger.info(`Subscribing to ${this.channel}`);
|
|
36
|
+
|
|
37
|
+
this.dexHelper.cache.subscribe(this.channel, (_, msg) => {
|
|
38
|
+
const before = Date.now();
|
|
39
|
+
const decodedMsg = JSON.parse(msg) as KeyValuePubSubMsg;
|
|
40
|
+
this.handleSubscription(decodedMsg);
|
|
41
|
+
const after = Date.now();
|
|
42
|
+
this.logger.info(`Decoding and handling took: ${after - before}ms`);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
publish(data: Record<string, unknown>, ttl: number) {
|
|
47
|
+
const expiresAt = Math.round(Date.now() / 1000) + ttl;
|
|
48
|
+
this.logger.info(
|
|
49
|
+
`Publishing keys: '${Object.keys(data)}', expiresAt: '${expiresAt}'`,
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
this.dexHelper.cache.publish(
|
|
53
|
+
this.channel,
|
|
54
|
+
JSON.stringify({ expiresAt, data }),
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
handleSubscription(msg: KeyValuePubSubMsg) {
|
|
59
|
+
const { expiresAt, data } = msg;
|
|
60
|
+
|
|
61
|
+
const now = Math.round(Date.now() / 1000);
|
|
62
|
+
// calculating ttl as message might come with the delay
|
|
63
|
+
const ttl = expiresAt - now;
|
|
64
|
+
|
|
65
|
+
if (ttl > 0) {
|
|
66
|
+
const keys = Object.keys(data);
|
|
67
|
+
for (const key of keys) {
|
|
68
|
+
this.localCache.set(key, data[key], ttl);
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
this.logger.error('Message has expired', {
|
|
72
|
+
now,
|
|
73
|
+
expiresAt,
|
|
74
|
+
diffInSeconds: now - expiresAt,
|
|
75
|
+
keys: Object.keys(data),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async getAndCache<T>(key: string): Promise<T | null> {
|
|
81
|
+
const localValue = this.localCache.get<T>(key);
|
|
82
|
+
|
|
83
|
+
if (localValue) {
|
|
84
|
+
return localValue;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const [value, ttl] = await Promise.all([
|
|
88
|
+
this.dexHelper.cache.get(this.dexKey, this.network, key),
|
|
89
|
+
this.dexHelper.cache.ttl(this.dexKey, this.network, key),
|
|
90
|
+
]);
|
|
91
|
+
|
|
92
|
+
if (value && ttl > 0) {
|
|
93
|
+
const parsedValue = JSON.parse(value);
|
|
94
|
+
this.localCache.set(key, parsedValue, ttl);
|
|
95
|
+
return parsedValue;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (this.defaultValue && this.defaultTTL && this.defaultTTL > 0) {
|
|
99
|
+
this.localCache.set(key, this.defaultValue, this.defaultTTL);
|
|
100
|
+
return this.defaultValue;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export class ExpHashPubSub {
|
|
108
|
+
localCache: NodeCache = new NodeCache();
|
|
109
|
+
|
|
110
|
+
logger: Logger;
|
|
111
|
+
|
|
112
|
+
constructor(
|
|
113
|
+
private dexHelper: IDexHelper,
|
|
114
|
+
private hashKey: string,
|
|
115
|
+
// in seconds
|
|
116
|
+
private ttl: number,
|
|
117
|
+
) {
|
|
118
|
+
this.hashKey = hashKey;
|
|
119
|
+
this.logger = this.dexHelper.getLogger(`ExpKeyValuePubSub_${this.hashKey}`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
subscribe() {
|
|
123
|
+
this.logger.info(`Subscribing`);
|
|
124
|
+
|
|
125
|
+
this.dexHelper.cache.subscribe(this.hashKey, (_, msg) => {
|
|
126
|
+
const before = Date.now();
|
|
127
|
+
const decodedMsg = Utils.Parse(msg) as KeyValuePubSubMsg;
|
|
128
|
+
this.handleSubscription(decodedMsg);
|
|
129
|
+
const after = Date.now();
|
|
130
|
+
this.logger.info(`Decoding and handling took: ${after - before}ms`);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
publish(data: Record<string, unknown>) {
|
|
135
|
+
if (Object.keys(data).length > 0) {
|
|
136
|
+
const expiresAt = Math.round(Date.now() / 1000) + this.ttl;
|
|
137
|
+
this.logger.info(
|
|
138
|
+
`Publishing keys: '${Object.keys(data)}', expiresAt: '${expiresAt}'`,
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
this.dexHelper.cache.publish(
|
|
142
|
+
this.hashKey,
|
|
143
|
+
Utils.Serialize({ expiresAt, data }),
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
handleSubscription(msg: KeyValuePubSubMsg) {
|
|
149
|
+
const { expiresAt, data } = msg;
|
|
150
|
+
this.logger.info(
|
|
151
|
+
`Received subscription, keys: '${Object.keys(
|
|
152
|
+
data,
|
|
153
|
+
)}', expiresAt: '${expiresAt}'`,
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
const now = Math.round(Date.now() / 1000);
|
|
157
|
+
// calculating ttl as message might come with the delay
|
|
158
|
+
const ttl = expiresAt - now;
|
|
159
|
+
|
|
160
|
+
if (ttl > 0) {
|
|
161
|
+
const keys = Object.keys(data);
|
|
162
|
+
for (const key of keys) {
|
|
163
|
+
this.localCache.set(key, data[key], ttl);
|
|
164
|
+
}
|
|
165
|
+
} else {
|
|
166
|
+
this.logger.error('Message has expired', {
|
|
167
|
+
now,
|
|
168
|
+
expiresAt,
|
|
169
|
+
diffInSeconds: now - expiresAt,
|
|
170
|
+
keys: Object.keys(data),
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async getAndCache<T>(key: string): Promise<T | null> {
|
|
176
|
+
const localValue = this.localCache.get<T>(key);
|
|
177
|
+
|
|
178
|
+
if (localValue !== undefined) {
|
|
179
|
+
this.logger.info(`Returning from local cache: '${key}'`);
|
|
180
|
+
return localValue;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
this.logger.info(`Returning from external cache: '${key}'`);
|
|
184
|
+
|
|
185
|
+
const value = await this.dexHelper.cache.hget(this.hashKey, key);
|
|
186
|
+
|
|
187
|
+
if (value && this.ttl > 0) {
|
|
188
|
+
const parsedValue = Utils.Parse(value);
|
|
189
|
+
this.localCache.set(key, parsedValue, this.ttl);
|
|
190
|
+
return parsedValue;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export class NonExpSetPubSub {
|
|
198
|
+
channel: string;
|
|
199
|
+
network: Network;
|
|
200
|
+
set = new Set<string>();
|
|
201
|
+
|
|
202
|
+
logger: Logger;
|
|
203
|
+
|
|
204
|
+
constructor(
|
|
205
|
+
private dexHelper: IDexHelper,
|
|
206
|
+
private dexKey: string,
|
|
207
|
+
channel: string,
|
|
208
|
+
) {
|
|
209
|
+
this.network = this.dexHelper.config.data.network;
|
|
210
|
+
this.channel = `${this.network}_${this.dexKey}_${channel}`;
|
|
211
|
+
|
|
212
|
+
this.logger = this.dexHelper.getLogger(`NonExpSetPubSub_${this.channel}`);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async initializeAndSubscribe(initialSet: string[]) {
|
|
216
|
+
this.logger.info(`initializeAndSubscribe with ${initialSet}`);
|
|
217
|
+
|
|
218
|
+
for (const member of initialSet) {
|
|
219
|
+
this.set.add(member);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
this.subscribe();
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
subscribe() {
|
|
226
|
+
this.logger.info(`Subscribing`);
|
|
227
|
+
|
|
228
|
+
this.dexHelper.cache.subscribe(this.channel, (_, msg) => {
|
|
229
|
+
const decodedMsg = JSON.parse(msg) as SetPubSubMsg;
|
|
230
|
+
this.handleSubscription(decodedMsg);
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
publish(msg: SetPubSubMsg) {
|
|
235
|
+
if (msg.length > 0) {
|
|
236
|
+
this.logger.info(`Publishing msg: '${msg}'`);
|
|
237
|
+
this.dexHelper.cache.publish(this.channel, JSON.stringify(msg));
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
handleSubscription(set: SetPubSubMsg) {
|
|
242
|
+
this.logger.info(`Received subscription msg: '${set}'`);
|
|
243
|
+
|
|
244
|
+
for (const key of set) {
|
|
245
|
+
this.set.add(key);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
async has(key: string) {
|
|
250
|
+
return this.set.has(key);
|
|
251
|
+
}
|
|
252
|
+
}
|
package/.idea/aws.xml
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<project version="4">
|
|
3
|
-
<component name="accountSettings">
|
|
4
|
-
<option name="activeProfile" value="profile:default" />
|
|
5
|
-
<option name="activeRegion" value="us-east-1" />
|
|
6
|
-
<option name="recentlyUsedProfiles">
|
|
7
|
-
<list>
|
|
8
|
-
<option value="profile:default" />
|
|
9
|
-
</list>
|
|
10
|
-
</option>
|
|
11
|
-
<option name="recentlyUsedRegions">
|
|
12
|
-
<list>
|
|
13
|
-
<option value="us-east-1" />
|
|
14
|
-
</list>
|
|
15
|
-
</option>
|
|
16
|
-
</component>
|
|
17
|
-
</project>
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
<component name="ProjectCodeStyleConfiguration">
|
|
2
|
-
<code_scheme name="Project" version="173">
|
|
3
|
-
<ScalaCodeStyleSettings>
|
|
4
|
-
<option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" />
|
|
5
|
-
</ScalaCodeStyleSettings>
|
|
6
|
-
<TypeScriptCodeStyleSettings version="0">
|
|
7
|
-
<option name="SPACE_WITHIN_ARRAY_INITIALIZER_BRACKETS" value="true" />
|
|
8
|
-
<option name="USE_DOUBLE_QUOTES" value="false" />
|
|
9
|
-
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
|
10
|
-
</TypeScriptCodeStyleSettings>
|
|
11
|
-
<codeStyleSettings language="TypeScript">
|
|
12
|
-
<indentOptions>
|
|
13
|
-
<option name="INDENT_SIZE" value="2" />
|
|
14
|
-
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
|
15
|
-
<option name="TAB_SIZE" value="2" />
|
|
16
|
-
</indentOptions>
|
|
17
|
-
</codeStyleSettings>
|
|
18
|
-
</code_scheme>
|
|
19
|
-
</component>
|
package/.idea/misc.xml
DELETED
package/.idea/modules.xml
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<project version="4">
|
|
3
|
-
<component name="ProjectModuleManager">
|
|
4
|
-
<modules>
|
|
5
|
-
<module fileurl="file://$PROJECT_DIR$/.idea/paraswap-dex-lib.iml" filepath="$PROJECT_DIR$/.idea/paraswap-dex-lib.iml" />
|
|
6
|
-
</modules>
|
|
7
|
-
</component>
|
|
8
|
-
</project>
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<module type="JAVA_MODULE" version="4">
|
|
3
|
-
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
|
4
|
-
<exclude-output />
|
|
5
|
-
<content url="file://$MODULE_DIR$" />
|
|
6
|
-
<orderEntry type="inheritedJdk" />
|
|
7
|
-
<orderEntry type="sourceFolder" forTests="false" />
|
|
8
|
-
</component>
|
|
9
|
-
</module>
|