@paraswap/dex-lib 2.36.0 → 2.36.2-dexalot
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/abi/dexalot/DexalotMainnetRFQ.json +887 -0
- package/build/config.js +2 -0
- package/build/config.js.map +1 -1
- package/build/dex/dexalot/config.d.ts +4 -0
- package/build/dex/dexalot/config.js +18 -0
- package/build/dex/dexalot/config.js.map +1 -0
- package/build/dex/dexalot/constants.d.ts +16 -0
- package/build/dex/dexalot/constants.js +23 -0
- package/build/dex/dexalot/constants.js.map +1 -0
- package/build/dex/dexalot/dexalot.d.ts +66 -0
- package/build/dex/dexalot/dexalot.js +603 -0
- package/build/dex/dexalot/dexalot.js.map +1 -0
- package/build/dex/dexalot/rate-fetcher.d.ts +27 -0
- package/build/dex/dexalot/rate-fetcher.js +101 -0
- package/build/dex/dexalot/rate-fetcher.js.map +1 -0
- package/build/dex/dexalot/types.d.ts +106 -0
- package/build/dex/dexalot/types.js +12 -0
- package/build/dex/dexalot/types.js.map +1 -0
- package/build/dex/dexalot/validators.d.ts +5 -0
- package/build/dex/dexalot/validators.js +45 -0
- package/build/dex/dexalot/validators.js.map +1 -0
- package/build/dex/index.js +2 -0
- package/build/dex/index.js.map +1 -1
- package/build/types.d.ts +1 -0
- package/package.json +1 -1
- package/src/abi/dexalot/DexalotMainnetRFQ.json +887 -0
- package/src/config.ts +3 -0
- package/src/dex/dexalot/config.ts +18 -0
- package/src/dex/dexalot/constants.ts +31 -0
- package/src/dex/dexalot/dexalot-e2e.test.ts +192 -0
- package/src/dex/dexalot/dexalot-integration.test.ts +188 -0
- package/src/dex/dexalot/dexalot.ts +911 -0
- package/src/dex/dexalot/rate-fetcher.ts +187 -0
- package/src/dex/dexalot/types.ts +122 -0
- package/src/dex/dexalot/validators.ts +46 -0
- package/src/dex/index.ts +2 -0
- package/src/types.ts +1 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { IDexHelper } from '../../dex-helper';
|
|
2
|
+
import { Fetcher } from '../../lib/fetcher/fetcher';
|
|
3
|
+
import { validateAndCast } from '../../lib/validators';
|
|
4
|
+
import { Logger, Token } from '../../types';
|
|
5
|
+
import {
|
|
6
|
+
DexalotRateFetcherConfig,
|
|
7
|
+
DexalotPairsResponse,
|
|
8
|
+
PairDataMap,
|
|
9
|
+
DexalotPricesResponse,
|
|
10
|
+
PriceDataMap,
|
|
11
|
+
DexalotBlacklistResponse,
|
|
12
|
+
} from './types';
|
|
13
|
+
import {
|
|
14
|
+
pricesResponseValidator,
|
|
15
|
+
pairsResponseValidator,
|
|
16
|
+
blacklistResponseValidator,
|
|
17
|
+
} from './validators';
|
|
18
|
+
import { Network } from '../../constants';
|
|
19
|
+
|
|
20
|
+
export class RateFetcher {
|
|
21
|
+
private pairsFetcher: Fetcher<DexalotPairsResponse>;
|
|
22
|
+
private pairsCacheKey: string;
|
|
23
|
+
private pairsCacheTTL: number;
|
|
24
|
+
|
|
25
|
+
private rateFetcher: Fetcher<DexalotPricesResponse>;
|
|
26
|
+
private pricesCacheKey: string;
|
|
27
|
+
private pricesCacheTTL: number;
|
|
28
|
+
|
|
29
|
+
private tokensAddrCacheKey: string;
|
|
30
|
+
private tokensCacheKey: string;
|
|
31
|
+
private tokensCacheTTL: number;
|
|
32
|
+
|
|
33
|
+
private blacklistFetcher: Fetcher<DexalotBlacklistResponse>;
|
|
34
|
+
private blacklistCacheKey: string;
|
|
35
|
+
|
|
36
|
+
constructor(
|
|
37
|
+
private dexHelper: IDexHelper,
|
|
38
|
+
private dexKey: string,
|
|
39
|
+
private network: Network,
|
|
40
|
+
private logger: Logger,
|
|
41
|
+
config: DexalotRateFetcherConfig,
|
|
42
|
+
) {
|
|
43
|
+
this.pairsCacheKey = config.rateConfig.pairsCacheKey;
|
|
44
|
+
this.pairsCacheTTL = config.rateConfig.pairsCacheTTLSecs;
|
|
45
|
+
this.pricesCacheKey = config.rateConfig.pricesCacheKey;
|
|
46
|
+
this.pricesCacheTTL = config.rateConfig.pricesCacheTTLSecs;
|
|
47
|
+
this.tokensAddrCacheKey = config.rateConfig.tokensAddrCacheKey;
|
|
48
|
+
this.tokensCacheKey = config.rateConfig.tokensCacheKey;
|
|
49
|
+
this.tokensCacheTTL = config.rateConfig.tokensCacheTTLSecs;
|
|
50
|
+
this.blacklistCacheKey = config.rateConfig.blacklistCacheKey;
|
|
51
|
+
|
|
52
|
+
this.pairsFetcher = new Fetcher<DexalotPairsResponse>(
|
|
53
|
+
dexHelper.httpRequest,
|
|
54
|
+
{
|
|
55
|
+
info: {
|
|
56
|
+
requestOptions: config.rateConfig.pairsReqParams,
|
|
57
|
+
caster: (data: unknown) => {
|
|
58
|
+
return validateAndCast<DexalotPairsResponse>(
|
|
59
|
+
data,
|
|
60
|
+
pairsResponseValidator,
|
|
61
|
+
);
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
handler: this.handlePairsResponse.bind(this),
|
|
65
|
+
},
|
|
66
|
+
config.rateConfig.pairsIntervalMs,
|
|
67
|
+
logger,
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
this.rateFetcher = new Fetcher<DexalotPricesResponse>(
|
|
71
|
+
dexHelper.httpRequest,
|
|
72
|
+
{
|
|
73
|
+
info: {
|
|
74
|
+
requestOptions: config.rateConfig.pricesReqParams,
|
|
75
|
+
caster: (data: unknown) => {
|
|
76
|
+
return validateAndCast<DexalotPricesResponse>(
|
|
77
|
+
data,
|
|
78
|
+
pricesResponseValidator,
|
|
79
|
+
);
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
handler: this.handleRatesResponse.bind(this),
|
|
83
|
+
},
|
|
84
|
+
config.rateConfig.pricesIntervalMs,
|
|
85
|
+
logger,
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
this.blacklistFetcher = new Fetcher<DexalotBlacklistResponse>(
|
|
89
|
+
dexHelper.httpRequest,
|
|
90
|
+
{
|
|
91
|
+
info: {
|
|
92
|
+
requestOptions: config.rateConfig.blacklistReqParams,
|
|
93
|
+
caster: (data: unknown) => {
|
|
94
|
+
return validateAndCast<DexalotBlacklistResponse>(
|
|
95
|
+
data,
|
|
96
|
+
blacklistResponseValidator,
|
|
97
|
+
);
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
handler: this.handleBlacklistResponse.bind(this),
|
|
101
|
+
},
|
|
102
|
+
config.rateConfig.blacklistIntervalMs,
|
|
103
|
+
logger,
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
start() {
|
|
108
|
+
this.pairsFetcher.startPolling();
|
|
109
|
+
this.rateFetcher.startPolling();
|
|
110
|
+
this.blacklistFetcher.startPolling();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
stop() {
|
|
114
|
+
this.pairsFetcher.stopPolling();
|
|
115
|
+
this.rateFetcher.stopPolling();
|
|
116
|
+
this.blacklistFetcher.stopPolling();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private handlePairsResponse(resp: DexalotPairsResponse): void {
|
|
120
|
+
const pairs = resp;
|
|
121
|
+
const dexPairs: PairDataMap = {};
|
|
122
|
+
const tokenMap: { [address: string]: Token } = {};
|
|
123
|
+
const tokenAddrMap: { [symbol: string]: string } = {};
|
|
124
|
+
Object.keys(pairs).forEach(pair => {
|
|
125
|
+
dexPairs[pair.toLowerCase()] = pairs[pair];
|
|
126
|
+
tokenAddrMap[pairs[pair].base.toLowerCase()] =
|
|
127
|
+
pairs[pair].baseAddress.toLowerCase();
|
|
128
|
+
tokenAddrMap[pairs[pair].quote.toLowerCase()] =
|
|
129
|
+
pairs[pair].quoteAddress.toLowerCase();
|
|
130
|
+
tokenMap[pairs[pair].baseAddress.toLowerCase()] = {
|
|
131
|
+
address: pairs[pair].baseAddress.toLowerCase(),
|
|
132
|
+
symbol: pairs[pair].base,
|
|
133
|
+
decimals: pairs[pair].baseDecimals,
|
|
134
|
+
};
|
|
135
|
+
tokenMap[pairs[pair].quoteAddress.toLowerCase()] = {
|
|
136
|
+
address: pairs[pair].quoteAddress.toLowerCase(),
|
|
137
|
+
symbol: pairs[pair].quote,
|
|
138
|
+
decimals: pairs[pair].quoteDecimals,
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
this.dexHelper.cache.setex(
|
|
142
|
+
this.dexKey,
|
|
143
|
+
this.network,
|
|
144
|
+
this.pairsCacheKey,
|
|
145
|
+
this.pairsCacheTTL,
|
|
146
|
+
JSON.stringify(dexPairs),
|
|
147
|
+
);
|
|
148
|
+
this.dexHelper.cache.setex(
|
|
149
|
+
this.dexKey,
|
|
150
|
+
this.network,
|
|
151
|
+
this.tokensCacheKey,
|
|
152
|
+
this.tokensCacheTTL,
|
|
153
|
+
JSON.stringify(tokenMap),
|
|
154
|
+
);
|
|
155
|
+
this.dexHelper.cache.setex(
|
|
156
|
+
this.dexKey,
|
|
157
|
+
this.network,
|
|
158
|
+
this.tokensAddrCacheKey,
|
|
159
|
+
this.tokensCacheTTL,
|
|
160
|
+
JSON.stringify(tokenAddrMap),
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
private handleRatesResponse(resp: DexalotPricesResponse): void {
|
|
165
|
+
const { prices } = resp;
|
|
166
|
+
const dexPrices: PriceDataMap = {};
|
|
167
|
+
Object.keys(prices).forEach(pair => {
|
|
168
|
+
dexPrices[pair.toLowerCase()] = prices[pair];
|
|
169
|
+
});
|
|
170
|
+
this.dexHelper.cache.setex(
|
|
171
|
+
this.dexKey,
|
|
172
|
+
this.network,
|
|
173
|
+
this.pricesCacheKey,
|
|
174
|
+
this.pricesCacheTTL,
|
|
175
|
+
JSON.stringify(dexPrices),
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
private async handleBlacklistResponse(
|
|
180
|
+
resp: DexalotBlacklistResponse,
|
|
181
|
+
): Promise<void> {
|
|
182
|
+
const { blacklist } = resp;
|
|
183
|
+
for (const address of blacklist) {
|
|
184
|
+
this.dexHelper.cache.sadd(this.blacklistCacheKey, address.toLowerCase());
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { RequestHeaders } from '../../dex-helper';
|
|
2
|
+
import { Token } from '../../types';
|
|
3
|
+
|
|
4
|
+
type RFQOrder = {
|
|
5
|
+
nonceAndMeta: string;
|
|
6
|
+
expiry: number;
|
|
7
|
+
makerAsset: string;
|
|
8
|
+
takerAsset: string;
|
|
9
|
+
maker: string;
|
|
10
|
+
taker: string;
|
|
11
|
+
makerAmount: string;
|
|
12
|
+
takerAmount: string;
|
|
13
|
+
signature?: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type RFQResponse = {
|
|
17
|
+
order: RFQOrder;
|
|
18
|
+
signature: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type RFQResponseError = {
|
|
22
|
+
Reason: string;
|
|
23
|
+
ReasonCode: string;
|
|
24
|
+
Success: boolean;
|
|
25
|
+
RetryAfter?: number;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type DexalotData = {
|
|
29
|
+
quoteData?: RFQOrder;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export type DexParams = {
|
|
33
|
+
mainnetRFQAddress: string;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export enum ClobSide {
|
|
37
|
+
BID = 'BID',
|
|
38
|
+
ASK = 'ASK',
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export class DexalotRfqError extends Error {}
|
|
42
|
+
|
|
43
|
+
export type PairData = {
|
|
44
|
+
base: string;
|
|
45
|
+
quote: string;
|
|
46
|
+
liquidityUSD: number;
|
|
47
|
+
isSrcBase?: boolean;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export type PairDataMap = {
|
|
51
|
+
[pair: string]: PairData;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export type PairDataResp = {
|
|
55
|
+
base: string;
|
|
56
|
+
quote: string;
|
|
57
|
+
liquidityUSD: number;
|
|
58
|
+
baseAddress: string;
|
|
59
|
+
quoteAddress: string;
|
|
60
|
+
baseDecimals: number;
|
|
61
|
+
quoteDecimals: number;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export type DexalotPairsResponse = {
|
|
65
|
+
[pair: string]: PairDataResp;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
type PriceData = {
|
|
69
|
+
bids: string[][];
|
|
70
|
+
asks: string[][];
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export type PriceDataMap = {
|
|
74
|
+
[pair: string]: PriceData;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export type DexalotPricesResponse = {
|
|
78
|
+
prices: PriceDataMap;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export type TokenAddrDataMap = {
|
|
82
|
+
[symbol: string]: string;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export type TokenDataMap = {
|
|
86
|
+
[address: string]: Token;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export type DexalotBlacklistResponse = {
|
|
90
|
+
blacklist: string[];
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export type DexalotRateFetcherConfig = {
|
|
94
|
+
rateConfig: {
|
|
95
|
+
pairsReqParams: {
|
|
96
|
+
url: string;
|
|
97
|
+
headers?: RequestHeaders;
|
|
98
|
+
params?: any;
|
|
99
|
+
};
|
|
100
|
+
pricesReqParams: {
|
|
101
|
+
url: string;
|
|
102
|
+
headers?: RequestHeaders;
|
|
103
|
+
params?: any;
|
|
104
|
+
};
|
|
105
|
+
blacklistReqParams: {
|
|
106
|
+
url: string;
|
|
107
|
+
headers?: RequestHeaders;
|
|
108
|
+
params?: any;
|
|
109
|
+
};
|
|
110
|
+
pairsIntervalMs: number;
|
|
111
|
+
pricesIntervalMs: number;
|
|
112
|
+
blacklistIntervalMs: number;
|
|
113
|
+
pairsCacheKey: string;
|
|
114
|
+
pricesCacheKey: string;
|
|
115
|
+
tokensAddrCacheKey: string;
|
|
116
|
+
tokensCacheKey: string;
|
|
117
|
+
blacklistCacheKey: string;
|
|
118
|
+
pairsCacheTTLSecs: number;
|
|
119
|
+
pricesCacheTTLSecs: number;
|
|
120
|
+
tokensCacheTTLSecs: number;
|
|
121
|
+
};
|
|
122
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import joi from 'joi';
|
|
2
|
+
|
|
3
|
+
const pairValidator = joi.object({
|
|
4
|
+
base: joi.string().min(1).required(),
|
|
5
|
+
quote: joi.string().min(1).required(),
|
|
6
|
+
liquidityUSD: joi.number().min(0).required(),
|
|
7
|
+
baseAddress: joi.string().min(1).required(),
|
|
8
|
+
quoteAddress: joi.string().min(1).required(),
|
|
9
|
+
baseDecimals: joi.number().min(0).required(),
|
|
10
|
+
quoteDecimals: joi.number().min(0).required(),
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export const pairsResponseValidator = joi
|
|
14
|
+
.object()
|
|
15
|
+
.pattern(joi.string(), pairValidator);
|
|
16
|
+
|
|
17
|
+
const orderbookRecordValidator = joi
|
|
18
|
+
.array()
|
|
19
|
+
.items(joi.string().min(1))
|
|
20
|
+
.length(2);
|
|
21
|
+
|
|
22
|
+
const orderbookValidator = joi.object({
|
|
23
|
+
bids: joi.array().items(orderbookRecordValidator).required(),
|
|
24
|
+
asks: joi.array().items(orderbookRecordValidator).required(),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export const pricesResponseValidator = joi.object({
|
|
28
|
+
prices: joi.object().pattern(joi.string(), orderbookValidator),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const tokenValidator = joi.object({
|
|
32
|
+
symbol: joi.string().min(1).required(),
|
|
33
|
+
name: joi.string().min(1).required(),
|
|
34
|
+
description: joi.string().min(1).required(),
|
|
35
|
+
address: joi.string().min(1).required(),
|
|
36
|
+
decimals: joi.number().min(0).required(),
|
|
37
|
+
type: joi.string().min(1).required(),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
export const tokensResponseValidator = joi.object({
|
|
41
|
+
tokens: joi.object().pattern(joi.string(), tokenValidator),
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
export const blacklistResponseValidator = joi.object({
|
|
45
|
+
blacklist: joi.array().items(joi.string().min(1)).required(),
|
|
46
|
+
});
|
package/src/dex/index.ts
CHANGED
|
@@ -76,6 +76,7 @@ import { PancakeswapV3 } from './pancakeswap-v3/pancakeswap-v3';
|
|
|
76
76
|
import { Algebra } from './algebra/algebra';
|
|
77
77
|
import { QuickPerps } from './quick-perps/quick-perps';
|
|
78
78
|
import { NomiswapV2 } from './uniswap-v2/nomiswap-v2';
|
|
79
|
+
import { Dexalot } from './dexalot/dexalot';
|
|
79
80
|
|
|
80
81
|
const LegacyDexes = [
|
|
81
82
|
CurveV2,
|
|
@@ -102,6 +103,7 @@ const LegacyDexes = [
|
|
|
102
103
|
];
|
|
103
104
|
|
|
104
105
|
const Dexes = [
|
|
106
|
+
Dexalot,
|
|
105
107
|
CurveV1,
|
|
106
108
|
CurveFork,
|
|
107
109
|
Swerve,
|