@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.
Files changed (199) hide show
  1. package/.vscode/launch.json +53 -0
  2. package/.vscode/settings.json +2 -0
  3. package/.vscode/tasks.json +15 -0
  4. package/build/abi/{integral/pool.json → inception/inception-ineth-pool.json} +558 -537
  5. package/build/abi/inception/inception-ratio-feed.json +329 -0
  6. package/build/abi/inception/inception-vault.json +991 -0
  7. package/build/abi/uniswap-v3/AlienBaseV3Router.abi.json +52 -0
  8. package/build/abi/usual-m-smart-m/usualM.abi.json +483 -0
  9. package/build/abi/{integral/relayer.json → wombat/pool.json} +474 -721
  10. package/build/dex/aave-v1/aave-v1.d.ts +2 -1
  11. package/build/dex/aave-v1/aave-v1.js +23 -0
  12. package/build/dex/aave-v1/aave-v1.js.map +1 -1
  13. package/build/dex/aave-v2/tokens-avalanche.json +44 -0
  14. package/build/dex/aave-v2/tokens-mainnet.json +188 -0
  15. package/build/dex/aave-v2/tokens-polygon.json +44 -0
  16. package/build/dex/balancer-v3/abi/balancerBatchRouter.d.ts +729 -0
  17. package/build/dex/balancer-v3/abi/balancerBatchRouter.js +732 -0
  18. package/build/dex/balancer-v3/abi/balancerBatchRouter.js.map +1 -0
  19. package/build/dex/balancer-v3/abi/balancerRouter.d.ts +1406 -0
  20. package/build/dex/balancer-v3/abi/balancerRouter.js +1175 -0
  21. package/build/dex/balancer-v3/abi/balancerRouter.js.map +1 -0
  22. package/build/dex/balancer-v3/abi/vaultExtension.V3.d.ts +2081 -0
  23. package/build/dex/balancer-v3/abi/vaultExtension.V3.js +1851 -0
  24. package/build/dex/balancer-v3/abi/vaultExtension.V3.js.map +1 -0
  25. package/build/dex/balancer-v3/balancer-v3-sepolia-pools.d.ts +34 -0
  26. package/build/dex/balancer-v3/balancer-v3-sepolia-pools.js +406 -0
  27. package/build/dex/balancer-v3/balancer-v3-sepolia-pools.js.map +1 -0
  28. package/build/dex/bebop/bebop.js +2 -2
  29. package/build/dex/bebop/bebop.js.map +1 -1
  30. package/build/dex/cables/cables.js +7 -3
  31. package/build/dex/cables/cables.js.map +1 -1
  32. package/build/dex/curve-v1-factory/curve-v1-factory.js +6 -2
  33. package/build/dex/curve-v1-factory/curve-v1-factory.js.map +1 -1
  34. package/build/dex/curve-v1-factory/curve-v1-pool-manager.d.ts +1 -1
  35. package/build/dex/curve-v1-factory/curve-v1-pool-manager.js +8 -2
  36. package/build/dex/curve-v1-factory/curve-v1-pool-manager.js.map +1 -1
  37. package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.d.ts +3 -2
  38. package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.js +7 -5
  39. package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.js.map +1 -1
  40. package/build/dex/curve-v1-factory/state-polling-pools/polling-manager.d.ts +7 -4
  41. package/build/dex/curve-v1-factory/state-polling-pools/polling-manager.js +23 -11
  42. package/build/dex/curve-v1-factory/state-polling-pools/polling-manager.js.map +1 -1
  43. package/build/dex/dexalot/constants.d.ts +2 -2
  44. package/build/dex/dexalot/constants.js +2 -2
  45. package/build/dex/dexalot/dexalot.js +8 -4
  46. package/build/dex/dexalot/dexalot.js.map +1 -1
  47. package/build/dex/dexalot/rate-fetcher.d.ts +1 -1
  48. package/build/dex/dexalot/rate-fetcher.js.map +1 -1
  49. package/build/dex/generic-rfq/rate-fetcher.js +5 -5
  50. package/build/dex/generic-rfq/rate-fetcher.js.map +1 -1
  51. package/build/dex/inception/config.d.ts +4 -0
  52. package/build/dex/inception/config.js +109 -0
  53. package/build/dex/inception/config.js.map +1 -0
  54. package/build/dex/inception/inception-event-pool.d.ts +16 -0
  55. package/build/dex/inception/inception-event-pool.js +49 -0
  56. package/build/dex/inception/inception-event-pool.js.map +1 -0
  57. package/build/dex/inception/inception.d.ts +43 -0
  58. package/build/dex/inception/inception.js +180 -0
  59. package/build/dex/inception/inception.js.map +1 -0
  60. package/build/dex/inception/tokens.d.ts +9 -0
  61. package/build/dex/inception/tokens.js +28 -0
  62. package/build/dex/inception/tokens.js.map +1 -0
  63. package/build/dex/inception/types.d.ts +22 -0
  64. package/build/dex/inception/types.js +3 -0
  65. package/build/dex/inception/types.js.map +1 -0
  66. package/build/dex/inception/utils.d.ts +7 -0
  67. package/build/dex/inception/utils.js +58 -0
  68. package/build/dex/inception/utils.js.map +1 -0
  69. package/build/dex/jarvis.d.ts +2 -1
  70. package/build/dex/jarvis.js +58 -0
  71. package/build/dex/jarvis.js.map +1 -1
  72. package/build/dex/maker-psm/scripts/gem.abi.json +136 -0
  73. package/build/dex/maker-psm/scripts/validate-state.d.ts +0 -0
  74. package/build/dex/maker-psm/scripts/validate-state.js +185 -0
  75. package/build/dex/maker-psm/scripts/validate-state.js.map +1 -0
  76. package/build/dex/maker-psm/scripts/vat.abi.json +243 -0
  77. package/build/dex/platypus/platypus.d.ts +2 -1
  78. package/build/dex/platypus/platypus.js +45 -0
  79. package/build/dex/platypus/platypus.js.map +1 -1
  80. package/build/dex/solidly-v3/scripts/check-event-pool-event.d.ts +1 -0
  81. package/build/dex/solidly-v3/scripts/check-event-pool-event.js +53 -0
  82. package/build/dex/solidly-v3/scripts/check-event-pool-event.js.map +1 -0
  83. package/build/dex/stable-pool.js +1 -8
  84. package/build/dex/stable-pool.js.map +1 -1
  85. package/build/dex/swaap-v1/swaap-v1.d.ts +2 -1
  86. package/build/dex/swaap-v1/swaap-v1.js +14 -0
  87. package/build/dex/swaap-v1/swaap-v1.js.map +1 -1
  88. package/build/dex/swaap-v2/swaap-v2.js +2 -2
  89. package/build/dex/swaap-v2/swaap-v2.js.map +1 -1
  90. package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.d.ts +17 -0
  91. package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.js +64 -0
  92. package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.js.map +1 -0
  93. package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.d.ts +17 -0
  94. package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.js +79 -0
  95. package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.js.map +1 -0
  96. package/build/dex/uniswap-v3/uniswap-v3-pricing.d.ts +4 -0
  97. package/build/dex/uniswap-v3/uniswap-v3-pricing.js +43 -0
  98. package/build/dex/uniswap-v3/uniswap-v3-pricing.js.map +1 -0
  99. package/build/dex/uniswap-v3/uniswap-v3-worker.d.ts +1 -0
  100. package/build/dex/uniswap-v3/uniswap-v3-worker.js +10 -0
  101. package/build/dex/uniswap-v3/uniswap-v3-worker.js.map +1 -0
  102. package/build/dex/usual/usual-m-smart-m.d.ts +17 -0
  103. package/build/dex/usual/usual-m-smart-m.js +50 -0
  104. package/build/dex/usual/usual-m-smart-m.js.map +1 -0
  105. package/build/dex/usual-m-smart-m/config.d.ts +3 -0
  106. package/build/dex/usual-m-smart-m/config.js +13 -0
  107. package/build/dex/usual-m-smart-m/config.js.map +1 -0
  108. package/build/dex/usual-m-smart-m/types.d.ts +7 -0
  109. package/build/dex/usual-m-smart-m/types.js +3 -0
  110. package/build/dex/usual-m-smart-m/types.js.map +1 -0
  111. package/build/dex/usual-m-smart-m/usual-m-smart-m.d.ts +35 -0
  112. package/build/dex/usual-m-smart-m/usual-m-smart-m.js +161 -0
  113. package/build/dex/usual-m-smart-m/usual-m-smart-m.js.map +1 -0
  114. package/build/dex/usual-m-usd0/config.d.ts +3 -0
  115. package/build/dex/usual-m-usd0/config.js +14 -0
  116. package/build/dex/usual-m-usd0/config.js.map +1 -0
  117. package/build/dex/usual-m-usd0/types.d.ts +8 -0
  118. package/build/dex/usual-m-usd0/types.js +3 -0
  119. package/build/dex/usual-m-usd0/types.js.map +1 -0
  120. package/build/dex/usual-m-usd0/usual-m-usd0.d.ts +35 -0
  121. package/build/dex/usual-m-usd0/usual-m-usd0.js +159 -0
  122. package/build/dex/usual-m-usd0/usual-m-usd0.js.map +1 -0
  123. package/build/dex/zerox/index.d.ts +4 -26
  124. package/build/dex/zerox/index.js +50 -42
  125. package/build/dex/zerox/index.js.map +1 -1
  126. package/build/dex/zerox/types.d.ts +29 -0
  127. package/build/dex/zerox/types.js +8 -1
  128. package/build/dex/zerox/types.js.map +1 -1
  129. package/build/dex-helper/dummy-dex-helper.js +10 -0
  130. package/build/dex-helper/dummy-dex-helper.js.map +1 -1
  131. package/build/dex-helper/icache.d.ts +3 -0
  132. package/build/lib/pub-sub.d.ts +51 -0
  133. package/build/lib/pub-sub.js +199 -0
  134. package/build/lib/pub-sub.js.map +1 -0
  135. package/package.json +1 -1
  136. package/src/abi/fluid-dex/fluid-dex.abi.json +2 -4
  137. package/src/dex/bebop/bebop.ts +4 -2
  138. package/src/dex/cables/cables.ts +9 -3
  139. package/src/dex/curve-v1-factory/curve-v1-factory.ts +5 -1
  140. package/src/dex/curve-v1-factory/curve-v1-pool-manager.ts +17 -1
  141. package/src/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.ts +4 -4
  142. package/src/dex/curve-v1-factory/state-polling-pools/polling-manager.ts +32 -21
  143. package/src/dex/dexalot/constants.ts +2 -2
  144. package/src/dex/dexalot/dexalot.ts +11 -4
  145. package/src/dex/dexalot/rate-fetcher.ts +6 -6
  146. package/src/dex/generic-rfq/rate-fetcher.ts +10 -5
  147. package/src/dex/swaap-v2/swaap-v2.ts +4 -2
  148. package/src/dex-helper/dummy-dex-helper.ts +21 -0
  149. package/src/dex-helper/icache.ts +6 -0
  150. package/src/lib/pub-sub.ts +252 -0
  151. package/.idea/aws.xml +0 -17
  152. package/.idea/codeStyles/Project.xml +0 -19
  153. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  154. package/.idea/misc.xml +0 -6
  155. package/.idea/modules.xml +0 -8
  156. package/.idea/paraswap-dex-lib.iml +0 -9
  157. package/.idea/prettier.xml +0 -7
  158. package/.idea/vcs.xml +0 -6
  159. package/build/abi/integral/factory.json +0 -333
  160. package/build/abi/integral/oracle.json +0 -501
  161. package/build/dex/fluid-dex/fluid-dex-generate-pool.d.ts +0 -49
  162. package/build/dex/fluid-dex/fluid-dex-generate-pool.js +0 -104
  163. package/build/dex/fluid-dex/fluid-dex-generate-pool.js.map +0 -1
  164. package/build/dex/integral/config.d.ts +0 -4
  165. package/build/dex/integral/config.js +0 -20
  166. package/build/dex/integral/config.js.map +0 -1
  167. package/build/dex/integral/context.d.ts +0 -40
  168. package/build/dex/integral/context.js +0 -158
  169. package/build/dex/integral/context.js.map +0 -1
  170. package/build/dex/integral/integral-factory.d.ts +0 -24
  171. package/build/dex/integral/integral-factory.js +0 -95
  172. package/build/dex/integral/integral-factory.js.map +0 -1
  173. package/build/dex/integral/integral-pool.d.ts +0 -50
  174. package/build/dex/integral/integral-pool.js +0 -149
  175. package/build/dex/integral/integral-pool.js.map +0 -1
  176. package/build/dex/integral/integral-pricing.d.ts +0 -18
  177. package/build/dex/integral/integral-pricing.js +0 -114
  178. package/build/dex/integral/integral-pricing.js.map +0 -1
  179. package/build/dex/integral/integral-relayer.d.ts +0 -42
  180. package/build/dex/integral/integral-relayer.js +0 -192
  181. package/build/dex/integral/integral-relayer.js.map +0 -1
  182. package/build/dex/integral/integral-token.d.ts +0 -27
  183. package/build/dex/integral/integral-token.js +0 -59
  184. package/build/dex/integral/integral-token.js.map +0 -1
  185. package/build/dex/integral/integral.d.ts +0 -41
  186. package/build/dex/integral/integral.js +0 -376
  187. package/build/dex/integral/integral.js.map +0 -1
  188. package/build/dex/integral/types.d.ts +0 -85
  189. package/build/dex/integral/types.js +0 -9
  190. package/build/dex/integral/types.js.map +0 -1
  191. package/build/dex/integral/utils-e2e.d.ts +0 -9
  192. package/build/dex/integral/utils-e2e.js +0 -131
  193. package/build/dex/integral/utils-e2e.js.map +0 -1
  194. package/build/dex/integral/utils.d.ts +0 -17
  195. package/build/dex/integral/utils.js +0 -94
  196. package/build/dex/integral/utils.js.map +0 -1
  197. package/build/dex/trader-joe-v2.1/optimizer.d.ts +0 -2
  198. package/build/dex/trader-joe-v2.1/optimizer.js +0 -47
  199. 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
- static async fetchAndSetStatesFromRPC(
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
- static async masterUpdatePoolsInBatch(
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 StatePollingManager.fetchAndSetStatesFromRPC(
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
- static async slaveUpdatePoolsInBatch(
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 unparsedStateFromCache = await dexHelper.cache.hget(
159
- p.cacheStateKey,
179
+ const parsedState = await this.pubSub.getAndCache<PoolState>(
160
180
  p.poolIdentifier,
161
181
  );
162
- if (unparsedStateFromCache !== null) {
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 StatePollingManager.fetchAndSetStatesFromRPC(
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
- static async updatePoolsInBatch(
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 StatePollingManager.slaveUpdatePoolsInBatch(
237
- logger,
238
- dexHelper,
239
- pools,
240
- blockNumber,
241
- );
252
+ await this.slaveUpdatePoolsInBatch(logger, dexHelper, pools, blockNumber);
242
253
  } else {
243
- await StatePollingManager.masterUpdatePoolsInBatch(
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;
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 = 1000;
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.get(
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.get(
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.get(
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.get(
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
- DexalotRateFetcherConfig,
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.get(
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.get(
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.get(
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.get(
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.get(
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.get(
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.get(
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;
@@ -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>
@@ -1,5 +0,0 @@
1
- <component name="ProjectCodeStyleConfiguration">
2
- <state>
3
- <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
4
- </state>
5
- </component>
package/.idea/misc.xml DELETED
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectRootManager">
4
- <output url="file://$PROJECT_DIR$/out" />
5
- </component>
6
- </project>
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>