@paraswap/dex-lib 4.1.7-pub-sub.3 → 4.1.7-pub-sub.4
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/build/dex/dexalot/dexalot.d.ts +2 -9
- package/build/dex/dexalot/dexalot.js +18 -62
- package/build/dex/dexalot/dexalot.js.map +1 -1
- package/build/dex/dexalot/rate-fetcher.d.ts +19 -4
- package/build/dex/dexalot/rate-fetcher.js +112 -8
- package/build/dex/dexalot/rate-fetcher.js.map +1 -1
- package/build/dex/dexalot/types.d.ts +0 -1
- package/build/dex/generic-rfq/rate-fetcher.js +0 -12
- package/build/dex/generic-rfq/rate-fetcher.js.map +1 -1
- package/build/dex/hashflow/constants.d.ts +2 -2
- package/build/dex/hashflow/constants.js +2 -2
- package/build/dex/hashflow/hashflow.d.ts +1 -6
- package/build/dex/hashflow/hashflow.js +9 -34
- package/build/dex/hashflow/hashflow.js.map +1 -1
- package/build/dex/hashflow/rate-fetcher.d.ts +12 -2
- package/build/dex/hashflow/rate-fetcher.js +54 -6
- package/build/dex/hashflow/rate-fetcher.js.map +1 -1
- package/build/dex/hashflow/types.d.ts +0 -1
- package/build/lib/pub-sub.d.ts +0 -2
- package/build/lib/pub-sub.js +0 -12
- package/build/lib/pub-sub.js.map +1 -1
- package/package.json +1 -1
- package/src/dex/dexalot/dexalot.ts +27 -127
- package/src/dex/dexalot/rate-fetcher.ts +219 -9
- package/src/dex/dexalot/types.ts +0 -1
- package/src/dex/generic-rfq/rate-fetcher.ts +0 -30
- package/src/dex/hashflow/constants.ts +2 -2
- package/src/dex/hashflow/hashflow.ts +11 -67
- package/src/dex/hashflow/rate-fetcher.ts +106 -8
- package/src/dex/hashflow/types.ts +0 -1
- package/src/lib/pub-sub.ts +0 -27
|
@@ -2,9 +2,11 @@ import { Network } from '../../constants';
|
|
|
2
2
|
import { IDexHelper } from '../../dex-helper';
|
|
3
3
|
import { Fetcher } from '../../lib/fetcher/fetcher';
|
|
4
4
|
import { validateAndCast } from '../../lib/validators';
|
|
5
|
-
import { Logger, Token } from '../../types';
|
|
5
|
+
import { Address, Logger, Token } from '../../types';
|
|
6
6
|
import {
|
|
7
7
|
DexalotBlacklistResponse,
|
|
8
|
+
TokenDataMap,
|
|
9
|
+
TokenAddrDataMap,
|
|
8
10
|
DexalotPairsResponse,
|
|
9
11
|
DexalotPricesResponse,
|
|
10
12
|
DexalotRateFetcherConfig,
|
|
@@ -16,13 +18,21 @@ import {
|
|
|
16
18
|
pairsResponseValidator,
|
|
17
19
|
pricesResponseValidator,
|
|
18
20
|
} from './validators';
|
|
21
|
+
import {
|
|
22
|
+
DEXALOT_BLACKLIST_CACHES_TTL_S,
|
|
23
|
+
DEXALOT_RATE_LIMITED_TTL_S,
|
|
24
|
+
DEXALOT_RATELIMIT_CACHE_VALUE,
|
|
25
|
+
DEXALOT_RESTRICT_TTL_S,
|
|
26
|
+
DEXALOT_RESTRICTED_CACHE_KEY,
|
|
27
|
+
} from './constants';
|
|
28
|
+
import { ExpKeyValuePubSub, NonExpSetPubSub } from '../../lib/pub-sub';
|
|
19
29
|
|
|
20
30
|
export class RateFetcher {
|
|
21
31
|
private pairsFetcher: Fetcher<DexalotPairsResponse>;
|
|
22
32
|
private pairsCacheKey: string;
|
|
23
|
-
private pairsCacheTTL: number;
|
|
24
33
|
|
|
25
34
|
private rateFetcher: Fetcher<DexalotPricesResponse>;
|
|
35
|
+
private rateTokensPubSub: ExpKeyValuePubSub;
|
|
26
36
|
private pricesCacheKey: string;
|
|
27
37
|
private pricesCacheTTL: number;
|
|
28
38
|
|
|
@@ -31,9 +41,12 @@ export class RateFetcher {
|
|
|
31
41
|
private tokensCacheTTL: number;
|
|
32
42
|
|
|
33
43
|
private blacklistFetcher: Fetcher<DexalotBlacklistResponse>;
|
|
44
|
+
private blacklistPubSub: NonExpSetPubSub;
|
|
34
45
|
private blacklistCacheKey: string;
|
|
35
46
|
private blacklistCacheTTL: number;
|
|
36
47
|
|
|
48
|
+
private restrictedPoolPubSub: ExpKeyValuePubSub;
|
|
49
|
+
|
|
37
50
|
constructor(
|
|
38
51
|
private dexHelper: IDexHelper,
|
|
39
52
|
private dexKey: string,
|
|
@@ -42,7 +55,6 @@ export class RateFetcher {
|
|
|
42
55
|
config: DexalotRateFetcherConfig,
|
|
43
56
|
) {
|
|
44
57
|
this.pairsCacheKey = config.rateConfig.pairsCacheKey;
|
|
45
|
-
this.pairsCacheTTL = config.rateConfig.pairsCacheTTLSecs;
|
|
46
58
|
this.pricesCacheKey = config.rateConfig.pricesCacheKey;
|
|
47
59
|
this.pricesCacheTTL = config.rateConfig.pricesCacheTTLSecs;
|
|
48
60
|
this.tokensAddrCacheKey = config.rateConfig.tokensAddrCacheKey;
|
|
@@ -51,6 +63,12 @@ export class RateFetcher {
|
|
|
51
63
|
this.blacklistCacheKey = config.rateConfig.blacklistCacheKey;
|
|
52
64
|
this.blacklistCacheTTL = config.rateConfig.blacklistCacheTTLSecs;
|
|
53
65
|
|
|
66
|
+
this.rateTokensPubSub = new ExpKeyValuePubSub(
|
|
67
|
+
dexHelper,
|
|
68
|
+
dexKey,
|
|
69
|
+
'rateTokens',
|
|
70
|
+
);
|
|
71
|
+
|
|
54
72
|
this.pairsFetcher = new Fetcher<DexalotPairsResponse>(
|
|
55
73
|
dexHelper.httpRequest,
|
|
56
74
|
{
|
|
@@ -87,6 +105,7 @@ export class RateFetcher {
|
|
|
87
105
|
logger,
|
|
88
106
|
);
|
|
89
107
|
|
|
108
|
+
this.blacklistPubSub = new NonExpSetPubSub(dexHelper, dexKey, 'blacklist');
|
|
90
109
|
this.blacklistFetcher = new Fetcher<DexalotBlacklistResponse>(
|
|
91
110
|
dexHelper.httpRequest,
|
|
92
111
|
{
|
|
@@ -104,12 +123,30 @@ export class RateFetcher {
|
|
|
104
123
|
config.rateConfig.blacklistIntervalMs,
|
|
105
124
|
logger,
|
|
106
125
|
);
|
|
126
|
+
|
|
127
|
+
this.restrictedPoolPubSub = new ExpKeyValuePubSub(
|
|
128
|
+
dexHelper,
|
|
129
|
+
dexKey,
|
|
130
|
+
'restricted-pool',
|
|
131
|
+
// using default value, we can lazy load non-restricted pools
|
|
132
|
+
// and restrict them by subscribing to this channel
|
|
133
|
+
'false',
|
|
134
|
+
DEXALOT_RESTRICT_TTL_S,
|
|
135
|
+
);
|
|
107
136
|
}
|
|
108
137
|
|
|
109
|
-
start() {
|
|
110
|
-
this.
|
|
111
|
-
|
|
112
|
-
|
|
138
|
+
async start() {
|
|
139
|
+
if (!this.dexHelper.config.isSlave) {
|
|
140
|
+
this.pairsFetcher.startPolling();
|
|
141
|
+
this.rateFetcher.startPolling();
|
|
142
|
+
this.blacklistFetcher.startPolling();
|
|
143
|
+
} else {
|
|
144
|
+
this.rateTokensPubSub.subscribe();
|
|
145
|
+
this.restrictedPoolPubSub.subscribe();
|
|
146
|
+
|
|
147
|
+
const initSet = await this.getAllBlacklisted();
|
|
148
|
+
this.blacklistPubSub.initializeAndSubscribe(initSet);
|
|
149
|
+
}
|
|
113
150
|
}
|
|
114
151
|
|
|
115
152
|
stop() {
|
|
@@ -145,7 +182,7 @@ export class RateFetcher {
|
|
|
145
182
|
this.dexKey,
|
|
146
183
|
this.network,
|
|
147
184
|
this.pairsCacheKey,
|
|
148
|
-
this.
|
|
185
|
+
this.tokensCacheTTL,
|
|
149
186
|
JSON.stringify(dexPairs),
|
|
150
187
|
);
|
|
151
188
|
|
|
@@ -164,6 +201,15 @@ export class RateFetcher {
|
|
|
164
201
|
this.tokensCacheTTL,
|
|
165
202
|
JSON.stringify(tokenAddrMap),
|
|
166
203
|
);
|
|
204
|
+
|
|
205
|
+
this.rateTokensPubSub.publish(
|
|
206
|
+
{
|
|
207
|
+
[this.pairsCacheKey]: dexPairs,
|
|
208
|
+
[this.tokensCacheKey]: tokenMap,
|
|
209
|
+
[this.tokensAddrCacheKey]: tokenAddrMap,
|
|
210
|
+
},
|
|
211
|
+
this.tokensCacheTTL,
|
|
212
|
+
);
|
|
167
213
|
}
|
|
168
214
|
|
|
169
215
|
private handleRatesResponse(resp: DexalotPricesResponse): void {
|
|
@@ -180,18 +226,182 @@ export class RateFetcher {
|
|
|
180
226
|
this.pricesCacheTTL,
|
|
181
227
|
JSON.stringify(dexPrices),
|
|
182
228
|
);
|
|
229
|
+
|
|
230
|
+
this.rateTokensPubSub.publish(
|
|
231
|
+
{ [this.pricesCacheKey]: dexPrices },
|
|
232
|
+
this.pricesCacheTTL,
|
|
233
|
+
);
|
|
183
234
|
}
|
|
184
235
|
|
|
185
236
|
private async handleBlacklistResponse(
|
|
186
237
|
resp: DexalotBlacklistResponse,
|
|
187
238
|
): Promise<void> {
|
|
188
239
|
const { blacklist } = resp;
|
|
240
|
+
const data = blacklist.map(item => item.toLowerCase());
|
|
189
241
|
this.dexHelper.cache.setex(
|
|
190
242
|
this.dexKey,
|
|
191
243
|
this.network,
|
|
192
244
|
this.blacklistCacheKey,
|
|
193
245
|
this.blacklistCacheTTL,
|
|
194
|
-
JSON.stringify(
|
|
246
|
+
JSON.stringify(data),
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
this.blacklistPubSub.publish(data);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
async getCachedTokens(): Promise<TokenDataMap | null> {
|
|
253
|
+
const cachedTokens = await this.rateTokensPubSub.getAndCache(
|
|
254
|
+
this.tokensCacheKey,
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
if (cachedTokens) {
|
|
258
|
+
return cachedTokens as TokenDataMap;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
async getCachedPairs(): Promise<PairDataMap | null> {
|
|
265
|
+
const cachedPairs = await this.rateTokensPubSub.getAndCache(
|
|
266
|
+
this.pairsCacheKey,
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
if (cachedPairs) {
|
|
270
|
+
return cachedPairs as PairDataMap;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
async getCachedTokensAddr(): Promise<TokenAddrDataMap | null> {
|
|
277
|
+
const cachedTokensAddr = await this.rateTokensPubSub.getAndCache(
|
|
278
|
+
this.tokensAddrCacheKey,
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
if (cachedTokensAddr) {
|
|
282
|
+
return cachedTokensAddr as TokenAddrDataMap;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
async setBlacklist(
|
|
289
|
+
txOrigin: Address,
|
|
290
|
+
ttl: number = DEXALOT_BLACKLIST_CACHES_TTL_S,
|
|
291
|
+
): Promise<boolean> {
|
|
292
|
+
const blacklist = await this.getAllBlacklisted();
|
|
293
|
+
|
|
294
|
+
blacklist.push(txOrigin.toLowerCase());
|
|
295
|
+
|
|
296
|
+
this.dexHelper.cache.setex(
|
|
297
|
+
this.dexKey,
|
|
298
|
+
this.network,
|
|
299
|
+
this.blacklistCacheKey,
|
|
300
|
+
ttl,
|
|
301
|
+
JSON.stringify(blacklist),
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
this.blacklistPubSub.publish([txOrigin.toLowerCase()]);
|
|
305
|
+
|
|
306
|
+
return true;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
async getAllBlacklisted(): Promise<string[]> {
|
|
310
|
+
const cachedBlacklist = await this.dexHelper.cache.get(
|
|
311
|
+
this.dexKey,
|
|
312
|
+
this.network,
|
|
313
|
+
this.blacklistCacheKey,
|
|
195
314
|
);
|
|
315
|
+
|
|
316
|
+
if (cachedBlacklist) {
|
|
317
|
+
return JSON.parse(cachedBlacklist);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return [];
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
async isBlacklisted(txOrigin: Address): Promise<boolean> {
|
|
324
|
+
const blacklisted = await this.blacklistPubSub.has(txOrigin.toLowerCase());
|
|
325
|
+
|
|
326
|
+
return blacklisted;
|
|
327
|
+
|
|
328
|
+
/*
|
|
329
|
+
rate-limit check was only if blacklist data set was not available,
|
|
330
|
+
in the current implementation it should not be the case,
|
|
331
|
+
so skip next check
|
|
332
|
+
*/
|
|
333
|
+
// To not show pricing for rate limited users
|
|
334
|
+
if (await this.isRateLimited(txOrigin)) {
|
|
335
|
+
return true;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return false;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
async setRateLimited(txOrigin: Address, ttl = DEXALOT_RATE_LIMITED_TTL_S) {
|
|
342
|
+
await this.dexHelper.cache.setex(
|
|
343
|
+
this.dexKey,
|
|
344
|
+
this.network,
|
|
345
|
+
this.getRateLimitedKey(txOrigin),
|
|
346
|
+
ttl,
|
|
347
|
+
DEXALOT_RATELIMIT_CACHE_VALUE,
|
|
348
|
+
);
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
async isRateLimited(txOrigin: Address): Promise<boolean> {
|
|
353
|
+
const result = await this.dexHelper.cache.get(
|
|
354
|
+
this.dexKey,
|
|
355
|
+
this.network,
|
|
356
|
+
this.getRateLimitedKey(txOrigin),
|
|
357
|
+
);
|
|
358
|
+
return result === DEXALOT_RATELIMIT_CACHE_VALUE;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
getRateLimitedKey(address: Address) {
|
|
362
|
+
return `rate_limited_${address}`.toLowerCase();
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
async getCachedPrices(): Promise<PriceDataMap | null> {
|
|
366
|
+
const cachedPrices = await this.rateTokensPubSub.getAndCache(
|
|
367
|
+
this.pricesCacheKey,
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
if (cachedPrices) {
|
|
371
|
+
return cachedPrices as PriceDataMap;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
return null;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
async restrictPool(
|
|
378
|
+
poolIdentifier: string,
|
|
379
|
+
ttl: number = DEXALOT_RESTRICT_TTL_S,
|
|
380
|
+
): Promise<boolean> {
|
|
381
|
+
await this.dexHelper.cache.setex(
|
|
382
|
+
this.dexKey,
|
|
383
|
+
this.network,
|
|
384
|
+
this.getRestrictedPoolKey(poolIdentifier),
|
|
385
|
+
ttl,
|
|
386
|
+
'true',
|
|
387
|
+
);
|
|
388
|
+
|
|
389
|
+
await this.restrictedPoolPubSub.publish(
|
|
390
|
+
{ [this.getRestrictedPoolKey(poolIdentifier)]: 'true' },
|
|
391
|
+
ttl,
|
|
392
|
+
);
|
|
393
|
+
return true;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
async isRestrictedPool(poolIdentifier: string): Promise<boolean> {
|
|
397
|
+
const result = await this.restrictedPoolPubSub.getAndCache(
|
|
398
|
+
this.getRestrictedPoolKey(poolIdentifier),
|
|
399
|
+
);
|
|
400
|
+
|
|
401
|
+
return result === 'true';
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
getRestrictedPoolKey(poolIdentifier: string): string {
|
|
405
|
+
return `${DEXALOT_RESTRICTED_CACHE_KEY}-${poolIdentifier}`;
|
|
196
406
|
}
|
|
197
407
|
}
|
package/src/dex/dexalot/types.ts
CHANGED
|
@@ -46,7 +46,6 @@ export const reversePrice = (price: PriceAndAmountBigNumber) =>
|
|
|
46
46
|
price[1].times(price[0]),
|
|
47
47
|
] as PriceAndAmountBigNumber;
|
|
48
48
|
|
|
49
|
-
const logPrefix = 'RateFetched[pub_sub]';
|
|
50
49
|
export class RateFetcher {
|
|
51
50
|
private tokensFetcher: Fetcher<TokensResponse>;
|
|
52
51
|
private pairsFetcher: Fetcher<PairsResponse>;
|
|
@@ -168,7 +167,6 @@ export class RateFetcher {
|
|
|
168
167
|
}
|
|
169
168
|
|
|
170
169
|
async initialize() {
|
|
171
|
-
this.logger.info(`${logPrefix} Initializing rate fetcher`);
|
|
172
170
|
const isContract = await isContractAddress(
|
|
173
171
|
this.dexHelper.web3Provider,
|
|
174
172
|
this.config.maker,
|
|
@@ -181,10 +179,8 @@ export class RateFetcher {
|
|
|
181
179
|
}
|
|
182
180
|
|
|
183
181
|
if (this.dexHelper.config.isSlave) {
|
|
184
|
-
this.logger.info(`${logPrefix} Subscribing to prices pubsub`);
|
|
185
182
|
this.pricesPubSub.subscribe();
|
|
186
183
|
if (this.blacklistPubSub) {
|
|
187
|
-
this.logger.info(`${logPrefix} Subscribing to blacklist pubsub`);
|
|
188
184
|
const initSet = await this.dexHelper.cache.smembers(
|
|
189
185
|
this.blackListCacheKey,
|
|
190
186
|
);
|
|
@@ -194,7 +190,6 @@ export class RateFetcher {
|
|
|
194
190
|
}
|
|
195
191
|
|
|
196
192
|
start() {
|
|
197
|
-
this.logger.info(`${logPrefix} Starting rate fetcher`);
|
|
198
193
|
this.tokensFetcher.startPolling();
|
|
199
194
|
this.rateFetcher.startPolling();
|
|
200
195
|
this.pairsFetcher.startPolling();
|
|
@@ -204,7 +199,6 @@ export class RateFetcher {
|
|
|
204
199
|
}
|
|
205
200
|
|
|
206
201
|
stop() {
|
|
207
|
-
this.logger.info(`${logPrefix} Stopping rate fetcher`);
|
|
208
202
|
this.tokensFetcher.stopPolling();
|
|
209
203
|
this.pairsFetcher.stopPolling();
|
|
210
204
|
this.rateFetcher.stopPolling();
|
|
@@ -215,10 +209,6 @@ export class RateFetcher {
|
|
|
215
209
|
}
|
|
216
210
|
|
|
217
211
|
private handleTokensResponse(data: TokensResponse) {
|
|
218
|
-
this.logger.info(
|
|
219
|
-
`${logPrefix} Handling tokens response, tokens: `,
|
|
220
|
-
Object.keys(data.tokens).length,
|
|
221
|
-
);
|
|
222
212
|
for (const tokenName of Object.keys(data.tokens)) {
|
|
223
213
|
const token = data.tokens[tokenName];
|
|
224
214
|
token.address = token.address.toLowerCase();
|
|
@@ -236,10 +226,6 @@ export class RateFetcher {
|
|
|
236
226
|
}
|
|
237
227
|
|
|
238
228
|
private handlePairsResponse(resp: PairsResponse) {
|
|
239
|
-
this.logger.info(
|
|
240
|
-
`${logPrefix} Handling pairs response, pairs: `,
|
|
241
|
-
Object.keys(resp.pairs).length,
|
|
242
|
-
);
|
|
243
229
|
this.pairs = {};
|
|
244
230
|
|
|
245
231
|
const pairs: PairMap = {};
|
|
@@ -251,19 +237,11 @@ export class RateFetcher {
|
|
|
251
237
|
}
|
|
252
238
|
|
|
253
239
|
private handleBlackListResponse(resp: BlackListResponse) {
|
|
254
|
-
this.logger.info(
|
|
255
|
-
`${logPrefix} Handling blacklist response, blacklist length: `,
|
|
256
|
-
resp.blacklist.length,
|
|
257
|
-
);
|
|
258
240
|
for (const address of resp.blacklist) {
|
|
259
241
|
this.dexHelper.cache.sadd(this.blackListCacheKey, address.toLowerCase());
|
|
260
242
|
}
|
|
261
243
|
|
|
262
244
|
if (this.blacklistPubSub) {
|
|
263
|
-
this.logger.info(
|
|
264
|
-
`${logPrefix} Publishing blacklist to pubsub, blacklist length: `,
|
|
265
|
-
resp.blacklist.length,
|
|
266
|
-
);
|
|
267
245
|
this.blacklistPubSub.publish(resp.blacklist);
|
|
268
246
|
}
|
|
269
247
|
}
|
|
@@ -276,10 +254,6 @@ export class RateFetcher {
|
|
|
276
254
|
}
|
|
277
255
|
|
|
278
256
|
private handleRatesResponse(resp: RatesResponse) {
|
|
279
|
-
this.logger.info(
|
|
280
|
-
`${logPrefix} Handling rates response, prices length: `,
|
|
281
|
-
Object.keys(resp.prices).length,
|
|
282
|
-
);
|
|
283
257
|
const pubSubData: Record<string, unknown> = {};
|
|
284
258
|
const ttl = this.config.rateConfig.dataTTLS;
|
|
285
259
|
const pairs = this.pairs;
|
|
@@ -395,10 +369,6 @@ export class RateFetcher {
|
|
|
395
369
|
|
|
396
370
|
public async getAvailablePairs(): Promise<string[]> {
|
|
397
371
|
const pairs = await this.pricesPubSub.getAndCache<string[]>(`pairs`);
|
|
398
|
-
this.logger.info(
|
|
399
|
-
`${logPrefix} Getting available pairs, pairs: `,
|
|
400
|
-
pairs?.length,
|
|
401
|
-
);
|
|
402
372
|
if (!pairs) {
|
|
403
373
|
return [];
|
|
404
374
|
}
|
|
@@ -4,11 +4,11 @@ export const HASHFLOW_BLACKLIST_TTL_S = 60 * 60 * 24 * 7; // 7 days
|
|
|
4
4
|
|
|
5
5
|
export const HASHFLOW_MM_RESTRICT_TTL_S = 60 * 60;
|
|
6
6
|
|
|
7
|
-
export const HASHFLOW_PRICES_CACHES_TTL_S =
|
|
7
|
+
export const HASHFLOW_PRICES_CACHES_TTL_S = 5;
|
|
8
8
|
|
|
9
9
|
export const HASHFLOW_MARKET_MAKERS_CACHES_TTL_S = 30;
|
|
10
10
|
|
|
11
|
-
export const HASHFLOW_API_PRICES_POLLING_INTERVAL_MS =
|
|
11
|
+
export const HASHFLOW_API_PRICES_POLLING_INTERVAL_MS = 2000;
|
|
12
12
|
|
|
13
13
|
export const HASHFLOW_API_MARKET_MAKERS_POLLING_INTERVAL_MS = 28 * 1000; // 28 secs
|
|
14
14
|
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { ChainId } from '@hashflow/sdk';
|
|
2
2
|
import { Chain, ChainType, HashflowApi } from '@hashflow/taker-js';
|
|
3
|
-
import {
|
|
4
|
-
MarketMakersResponse,
|
|
5
|
-
PriceLevelsResponse,
|
|
6
|
-
RfqResponse,
|
|
7
|
-
} from '@hashflow/taker-js/dist/types/rest';
|
|
3
|
+
import { RfqResponse } from '@hashflow/taker-js/dist/types/rest';
|
|
8
4
|
import BigNumber from 'bignumber.js';
|
|
9
5
|
import { Interface } from 'ethers/lib/utils';
|
|
10
6
|
import { assert } from 'ts-essentials';
|
|
@@ -145,7 +141,6 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
|
|
|
145
141
|
},
|
|
146
142
|
headers: { Authorization: this.hashFlowAuthToken },
|
|
147
143
|
},
|
|
148
|
-
getCachedMarketMakers: this.getCachedMarketMakers.bind(this),
|
|
149
144
|
filterMarketMakers: this.getFilteredMarketMakers.bind(this),
|
|
150
145
|
pricesCacheKey: this.pricesCacheKey,
|
|
151
146
|
pricesCacheTTLSecs: HASHFLOW_PRICES_CACHES_TTL_S,
|
|
@@ -157,9 +152,7 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
|
|
|
157
152
|
}
|
|
158
153
|
|
|
159
154
|
async initializePricing(blockNumber: number): Promise<void> {
|
|
160
|
-
|
|
161
|
-
this.rateFetcher.start();
|
|
162
|
-
}
|
|
155
|
+
this.rateFetcher.start();
|
|
163
156
|
|
|
164
157
|
return;
|
|
165
158
|
}
|
|
@@ -198,7 +191,7 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
|
|
|
198
191
|
return [];
|
|
199
192
|
}
|
|
200
193
|
|
|
201
|
-
const levels = (await this.getCachedLevels()) || {};
|
|
194
|
+
const levels = (await this.rateFetcher.getCachedLevels()) || {};
|
|
202
195
|
const makers = Object.keys(levels);
|
|
203
196
|
|
|
204
197
|
return makers
|
|
@@ -381,32 +374,6 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
|
|
|
381
374
|
return undefined;
|
|
382
375
|
}
|
|
383
376
|
|
|
384
|
-
async getCachedMarketMakers(): Promise<
|
|
385
|
-
MarketMakersResponse['marketMakers'] | null
|
|
386
|
-
> {
|
|
387
|
-
const cachedMarketMakers = await this.dexHelper.cache.rawget(
|
|
388
|
-
this.marketMakersCacheKey,
|
|
389
|
-
);
|
|
390
|
-
|
|
391
|
-
if (cachedMarketMakers) {
|
|
392
|
-
return JSON.parse(
|
|
393
|
-
cachedMarketMakers,
|
|
394
|
-
) as MarketMakersResponse['marketMakers'];
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
return null;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
async getCachedLevels(): Promise<PriceLevelsResponse['levels'] | null> {
|
|
401
|
-
const cachedLevels = await this.dexHelper.cache.rawget(this.pricesCacheKey);
|
|
402
|
-
|
|
403
|
-
if (cachedLevels) {
|
|
404
|
-
return JSON.parse(cachedLevels) as PriceLevelsResponse['levels'];
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
return null;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
377
|
async getPricesVolume(
|
|
411
378
|
srcToken: Token,
|
|
412
379
|
destToken: Token,
|
|
@@ -434,7 +401,7 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
|
|
|
434
401
|
|
|
435
402
|
const marketMakersToUse = pools.map(p => p.split(`${prefix}_`).pop());
|
|
436
403
|
|
|
437
|
-
const levelsMap = (await this.getCachedLevels()) || {};
|
|
404
|
+
const levelsMap = (await this.rateFetcher.getCachedLevels()) || {};
|
|
438
405
|
|
|
439
406
|
Object.keys(levelsMap).forEach(mmKey => {
|
|
440
407
|
if (!marketMakersToUse.includes(mmKey)) {
|
|
@@ -715,7 +682,7 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
|
|
|
715
682
|
this.logger.warn(
|
|
716
683
|
`${this.dexKey}-${this.network}: Encountered restricted user=${options.userAddress}. Adding to local blacklist cache`,
|
|
717
684
|
);
|
|
718
|
-
await this.setBlacklist(options.userAddress);
|
|
685
|
+
await this.rateFetcher.setBlacklist(options.userAddress);
|
|
719
686
|
} else {
|
|
720
687
|
if (e instanceof TooStrictSlippageCheckError) {
|
|
721
688
|
this.logger.warn(
|
|
@@ -911,33 +878,6 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
|
|
|
911
878
|
};
|
|
912
879
|
}
|
|
913
880
|
|
|
914
|
-
getBlackListKey(address: Address) {
|
|
915
|
-
return `blacklist_${address}`.toLowerCase();
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
async isBlacklisted(txOrigin: Address): Promise<boolean> {
|
|
919
|
-
const result = await this.dexHelper.cache.get(
|
|
920
|
-
this.dexKey,
|
|
921
|
-
this.network,
|
|
922
|
-
this.getBlackListKey(txOrigin),
|
|
923
|
-
);
|
|
924
|
-
return result === 'blacklisted';
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
async setBlacklist(
|
|
928
|
-
txOrigin: Address,
|
|
929
|
-
ttl: number = HASHFLOW_BLACKLIST_TTL_S,
|
|
930
|
-
) {
|
|
931
|
-
await this.dexHelper.cache.setex(
|
|
932
|
-
this.dexKey,
|
|
933
|
-
this.network,
|
|
934
|
-
this.getBlackListKey(txOrigin),
|
|
935
|
-
ttl,
|
|
936
|
-
'blacklisted',
|
|
937
|
-
);
|
|
938
|
-
return true;
|
|
939
|
-
}
|
|
940
|
-
|
|
941
881
|
async getSimpleParam(
|
|
942
882
|
srcToken: string,
|
|
943
883
|
destToken: string,
|
|
@@ -1058,9 +998,9 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
|
|
|
1058
998
|
.wrapETH(tokenAddress)
|
|
1059
999
|
.toLowerCase();
|
|
1060
1000
|
|
|
1061
|
-
const makers = (await this.getCachedMarketMakers()) || [];
|
|
1001
|
+
const makers = (await this.rateFetcher.getCachedMarketMakers()) || [];
|
|
1062
1002
|
const filteredMakers = await this.getFilteredMarketMakers(makers);
|
|
1063
|
-
const pLevels = (await this.getCachedLevels()) || {};
|
|
1003
|
+
const pLevels = (await this.rateFetcher.getCachedLevels()) || {};
|
|
1064
1004
|
|
|
1065
1005
|
let baseToken: Token | undefined = undefined;
|
|
1066
1006
|
// TODO: Improve efficiency of this part. Quite inefficient way to determine
|
|
@@ -1120,4 +1060,8 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
|
|
|
1120
1060
|
this.rateFetcher.stop();
|
|
1121
1061
|
}
|
|
1122
1062
|
}
|
|
1063
|
+
|
|
1064
|
+
async isBlacklisted(txOrigin: Address): Promise<boolean> {
|
|
1065
|
+
return this.rateFetcher.isBlacklisted(txOrigin);
|
|
1066
|
+
}
|
|
1123
1067
|
}
|