@paraswap/dex-lib 3.8.38 → 3.8.39-bebop

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 (62) hide show
  1. package/build/abi/USDM.json +807 -0
  2. package/build/abi/bebop/BebopSettlement.abi.json +2137 -0
  3. package/build/abi/wUSDM.json +757 -0
  4. package/build/config.js +7 -0
  5. package/build/config.js.map +1 -1
  6. package/build/dex/bebop/bebop.d.ts +55 -0
  7. package/build/dex/bebop/bebop.js +524 -0
  8. package/build/dex/bebop/bebop.js.map +1 -0
  9. package/build/dex/bebop/config.d.ts +3 -0
  10. package/build/dex/bebop/config.js +38 -0
  11. package/build/dex/bebop/config.js.map +1 -0
  12. package/build/dex/bebop/constants.d.ts +9 -0
  13. package/build/dex/bebop/constants.js +13 -0
  14. package/build/dex/bebop/constants.js.map +1 -0
  15. package/build/dex/bebop/rate-fetcher.d.ts +22 -0
  16. package/build/dex/bebop/rate-fetcher.js +80 -0
  17. package/build/dex/bebop/rate-fetcher.js.map +1 -0
  18. package/build/dex/bebop/types.d.ts +76 -0
  19. package/build/dex/bebop/types.js +3 -0
  20. package/build/dex/bebop/types.js.map +1 -0
  21. package/build/dex/bebop/validators.d.ts +4 -0
  22. package/build/dex/bebop/validators.js +42 -0
  23. package/build/dex/bebop/validators.js.map +1 -0
  24. package/build/dex/bebop/websocket-fetcher.d.ts +35 -0
  25. package/build/dex/bebop/websocket-fetcher.js +87 -0
  26. package/build/dex/bebop/websocket-fetcher.js.map +1 -0
  27. package/build/dex/index.js +2 -0
  28. package/build/dex/index.js.map +1 -1
  29. package/build/dex/woo-fi-v2/woo-fi-v2-pool.d.ts +2 -2
  30. package/build/dex/woo-fi-v2/woo-fi-v2-pool.js +30 -9
  31. package/build/dex/woo-fi-v2/woo-fi-v2-pool.js.map +1 -1
  32. package/build/dex/woo-fi-v2/woo-fi-v2.js +1 -1
  33. package/build/dex/woo-fi-v2/woo-fi-v2.js.map +1 -1
  34. package/build/dex/wusdm/config.d.ts +3 -0
  35. package/build/dex/wusdm/config.js +29 -0
  36. package/build/dex/wusdm/config.js.map +1 -0
  37. package/build/dex/wusdm/types.d.ts +10 -0
  38. package/build/dex/wusdm/types.js +3 -0
  39. package/build/dex/wusdm/types.js.map +1 -0
  40. package/build/dex/wusdm/wusdm.d.ts +39 -0
  41. package/build/dex/wusdm/wusdm.js +212 -0
  42. package/build/dex/wusdm/wusdm.js.map +1 -0
  43. package/build/lib/fetcher/wsFetcher.d.ts +35 -0
  44. package/build/lib/fetcher/wsFetcher.js +87 -0
  45. package/build/lib/fetcher/wsFetcher.js.map +1 -0
  46. package/build/types.d.ts +1 -0
  47. package/package.json +4 -2
  48. package/src/abi/bebop/BebopSettlement.abi.json +2137 -0
  49. package/src/config.ts +8 -0
  50. package/src/dex/bebop/bebop-e2e.test.ts +195 -0
  51. package/src/dex/bebop/bebop-integration.test.ts +170 -0
  52. package/src/dex/bebop/bebop.ts +732 -0
  53. package/src/dex/bebop/config.ts +37 -0
  54. package/src/dex/bebop/constants.ts +9 -0
  55. package/src/dex/bebop/rate-fetcher.ts +138 -0
  56. package/src/dex/bebop/types.ts +81 -0
  57. package/src/dex/bebop/validators.ts +43 -0
  58. package/src/dex/index.ts +2 -0
  59. package/src/dex/woo-fi-v2/woo-fi-v2-pool.ts +58 -27
  60. package/src/dex/woo-fi-v2/woo-fi-v2.ts +1 -2
  61. package/src/lib/fetcher/wsFetcher.ts +126 -0
  62. package/src/types.ts +1 -0
@@ -0,0 +1,37 @@
1
+ import { DexParams } from './types';
2
+ import { DexConfigMap } from '../../types';
3
+ import { Network } from '../../constants';
4
+
5
+ export const BebopConfig: DexConfigMap<DexParams> = {
6
+ Bebop: {
7
+ [Network.MAINNET]: {
8
+ settlementAddress: '0xbbbbbBB520d69a9775E85b458C58c648259FAD5F',
9
+ chainName: 'ethereum',
10
+ middleTokens: [
11
+ '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
12
+ '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDT
13
+ '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH
14
+ ],
15
+ },
16
+ [Network.ARBITRUM]: {
17
+ settlementAddress: '0xbbbbbBB520d69a9775E85b458C58c648259FAD5F',
18
+ chainName: 'arbitrum',
19
+ middleTokens: [
20
+ '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8', // USDC.e
21
+ '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', // USDC
22
+ '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', // USDT
23
+ '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', // WETH
24
+ ],
25
+ },
26
+ [Network.BASE]: {
27
+ settlementAddress: '0xbbbbbBB520d69a9775E85b458C58c648259FAD5F',
28
+ chainName: 'base',
29
+ middleTokens: ['0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'],
30
+ },
31
+ [Network.OPTIMISM]: {
32
+ settlementAddress: '0xbbbbbBB520d69a9775E85b458C58c648259FAD5F',
33
+ chainName: 'optimism',
34
+ middleTokens: ['0x7F5c764cBc14f9669B88837ca1490cCa17c31607'],
35
+ },
36
+ },
37
+ };
@@ -0,0 +1,9 @@
1
+ export const BEBOP_INIT_TIMEOUT_MS = 5000;
2
+ export const BEBOP_PRICES_CACHE_TTL = 10;
3
+ export const BEBOP_TOKENS_CACHE_TTL = 60;
4
+ export const BEBOP_TOKENS_POLLING_INTERVAL_MS = 30 * 1000;
5
+ export const BEBOP_API_URL = 'https://api.bebop.xyz';
6
+ export const BEBOP_WS_API_URL = 'wss://api.bebop.xyz';
7
+ export const BEBOP_GAS_COST = 120_000;
8
+ export const BEBOP_AUTH_NAME = 'paraswap';
9
+ export const BEBOP_QUOTE_TIMEOUT_MS = 2000;
@@ -0,0 +1,138 @@
1
+ import { ETHER_ADDRESS, Network } from '../../constants';
2
+ import { IDexHelper } from '../../dex-helper';
3
+ import { Fetcher } from '../../lib/fetcher/fetcher';
4
+ import { validateAndCast } from '../../lib/validators';
5
+ import { Logger, Token } from '../../types';
6
+ import {
7
+ BebopPricingResponse,
8
+ BebopRateFetcherConfig,
9
+ BebopTokensResponse,
10
+ } from './types';
11
+ import { pricesResponseValidator, tokensResponseValidator } from './validators';
12
+ import { WebSocketFetcher } from '../../lib/fetcher/wsFetcher';
13
+
14
+ export class RateFetcher {
15
+ private pricesFetcher: WebSocketFetcher<BebopPricingResponse>;
16
+ private pricesCacheKey: string;
17
+ private pricesCacheTTL: number;
18
+
19
+ private tokensFetcher: Fetcher<BebopTokensResponse>;
20
+ private tokensAddrCacheKey: string;
21
+ private tokensCacheKey: string;
22
+ private tokensCacheTTL: number;
23
+
24
+ constructor(
25
+ private dexHelper: IDexHelper,
26
+ private dexKey: string,
27
+ private network: Network,
28
+ private logger: Logger,
29
+ config: BebopRateFetcherConfig,
30
+ ) {
31
+ this.pricesCacheKey = config.rateConfig.pricesCacheKey;
32
+ this.pricesCacheTTL = config.rateConfig.pricesCacheTTLSecs;
33
+ this.pricesFetcher = new WebSocketFetcher<BebopPricingResponse>(
34
+ {
35
+ info: {
36
+ requestOptions: config.rateConfig.pricesReqParams,
37
+ caster: (data: unknown) => {
38
+ return validateAndCast<BebopPricingResponse>(
39
+ data,
40
+ pricesResponseValidator,
41
+ );
42
+ },
43
+ },
44
+ handler: this.handlePricesResponse.bind(this),
45
+ },
46
+ logger,
47
+ );
48
+
49
+ this.tokensAddrCacheKey = config.rateConfig.tokensAddrCacheKey;
50
+ this.tokensCacheKey = config.rateConfig.tokensCacheKey;
51
+ this.tokensCacheTTL = config.rateConfig.tokensCacheTTLSecs;
52
+ this.tokensFetcher = new Fetcher<BebopTokensResponse>(
53
+ dexHelper.httpRequest,
54
+ {
55
+ info: {
56
+ requestOptions: config.rateConfig.tokensReqParams,
57
+ caster: (data: unknown) => {
58
+ return validateAndCast<BebopTokensResponse>(
59
+ data,
60
+ tokensResponseValidator,
61
+ );
62
+ },
63
+ },
64
+ handler: this.handleTokensResponse.bind(this),
65
+ },
66
+ config.rateConfig.tokensIntervalMs,
67
+ logger,
68
+ );
69
+ }
70
+
71
+ start() {
72
+ this.pricesFetcher.startPolling();
73
+ this.tokensFetcher.startPolling();
74
+ }
75
+
76
+ stop() {
77
+ this.pricesFetcher.stopPolling();
78
+ this.tokensFetcher.stopPolling();
79
+ }
80
+
81
+ private handleTokensResponse(resp: BebopTokensResponse): void {
82
+ const tokenMap: { [address: string]: Token } = {};
83
+ const tokenAddrMap: { [symbol: string]: Token } = {};
84
+
85
+ Object.keys(resp.tokens).forEach(tokenSymbol => {
86
+ const token = resp.tokens[tokenSymbol];
87
+ const tokenData = {
88
+ address: token.contractAddress.toLowerCase(),
89
+ symbol: token.ticker,
90
+ decimals: token.decimals,
91
+ };
92
+ tokenAddrMap[token.contractAddress.toLowerCase()] = tokenData;
93
+ tokenMap[token.ticker.toLowerCase()] = tokenData;
94
+ });
95
+
96
+ this.dexHelper.cache.setex(
97
+ this.dexKey,
98
+ this.network,
99
+ this.tokensCacheKey,
100
+ this.tokensCacheTTL,
101
+ JSON.stringify(tokenMap),
102
+ );
103
+
104
+ this.dexHelper.cache.setex(
105
+ this.dexKey,
106
+ this.network,
107
+ this.tokensAddrCacheKey,
108
+ this.tokensCacheTTL,
109
+ JSON.stringify(tokenAddrMap),
110
+ );
111
+ }
112
+
113
+ private handlePricesResponse(resp: BebopPricingResponse): void {
114
+ const wethAddress =
115
+ this.dexHelper.config.data.wrappedNativeTokenAddress.toLowerCase();
116
+ const normalizedPrices: BebopPricingResponse = {};
117
+ for (const [pair, levels] of Object.entries(resp)) {
118
+ normalizedPrices[pair.toLowerCase()] = levels;
119
+ const [base, quote] = pair.split('/');
120
+ // Also enter native token prices. Pricing doesn't come with these
121
+ if (
122
+ base.toLowerCase() === wethAddress ||
123
+ quote.toLowerCase() === wethAddress
124
+ ) {
125
+ const nativePair = pair.replace(base, ETHER_ADDRESS);
126
+ normalizedPrices[nativePair.toLowerCase()] = levels;
127
+ }
128
+ }
129
+
130
+ this.dexHelper.cache.setex(
131
+ this.dexKey,
132
+ this.network,
133
+ this.pricesCacheKey,
134
+ this.pricesCacheTTL,
135
+ JSON.stringify(normalizedPrices),
136
+ );
137
+ }
138
+ }
@@ -0,0 +1,81 @@
1
+ import { SwapSide } from '../../constants';
2
+ import { RequestHeaders } from '../../dex-helper';
3
+
4
+ export type BebopRateFetcherConfig = {
5
+ rateConfig: {
6
+ pricesReqParams: {
7
+ url: string;
8
+ headers?: RequestHeaders;
9
+ params?: any;
10
+ };
11
+ tokensReqParams: {
12
+ url: string;
13
+ headers?: RequestHeaders;
14
+ params?: any;
15
+ };
16
+ tokensIntervalMs: number;
17
+ pricesCacheKey: string;
18
+ tokensAddrCacheKey: string;
19
+ tokensCacheKey: string;
20
+ pricesCacheTTLSecs: number;
21
+ tokensCacheTTLSecs: number;
22
+ };
23
+ };
24
+
25
+ export type TokenDataMap = { [index: string]: BebopToken };
26
+
27
+ export type BebopToken = {
28
+ decimals: number;
29
+ contractAddress: string;
30
+ ticker: string;
31
+ };
32
+
33
+ export type BebopTokensResponse = {
34
+ tokens: { [symbol: string]: BebopToken };
35
+ };
36
+
37
+ export type BebopLevel = [price: number, size: number];
38
+
39
+ export type BebopPair = {
40
+ bids: BebopLevel[];
41
+ asks: BebopLevel[];
42
+ last_update_ts: number;
43
+ };
44
+
45
+ export type BebopPricingResponse = {
46
+ [pair: string]: BebopPair;
47
+ };
48
+
49
+ export interface BebopTx {
50
+ to: string;
51
+ value: string;
52
+ data: string;
53
+ from: string;
54
+ gas: number;
55
+ }
56
+
57
+ export type BebopTokenAmount = {
58
+ amount: string;
59
+ priceUsd: number;
60
+ };
61
+
62
+ // For now nothing but we may have to add something
63
+ export type BebopData = {
64
+ expiry?: number;
65
+ buyTokens?: { [address: string]: BebopTokenAmount };
66
+ sellTokens?: { [address: string]: BebopTokenAmount };
67
+ tx?: BebopTx;
68
+ };
69
+
70
+ export type DexParams = {
71
+ settlementAddress: string;
72
+ chainName: string;
73
+ middleTokens: string[];
74
+ };
75
+
76
+ export type RoutingInstruction = {
77
+ side: SwapSide; // Buy for bids, Sell for asks
78
+ book: BebopPair;
79
+ pair: string;
80
+ targetQuote: boolean;
81
+ };
@@ -0,0 +1,43 @@
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 levelValidator = joi.array().items(joi.number()).length(2);
18
+
19
+ const pairValidator = joi.object({
20
+ bids: joi.array().items(levelValidator).required(),
21
+ asks: joi.array().items(levelValidator).required(),
22
+ last_update_ts: joi.number().min(0).required(),
23
+ });
24
+
25
+ export const pricesResponseValidator = joi
26
+ .object()
27
+ .pattern(joi.string(), pairValidator);
28
+
29
+ const tokenValidator = joi
30
+ .object({
31
+ ticker: joi.string().min(1).required(),
32
+ contractAddress: joi.string().min(1).required(),
33
+ decimals: joi.number().min(0).required(),
34
+ })
35
+ .unknown(true);
36
+
37
+ export const tokensResponseValidator = joi.object({
38
+ tokens: joi.object().pattern(joi.string(), tokenValidator),
39
+ });
40
+
41
+ export const blacklistResponseValidator = joi.object({
42
+ blacklist: joi.array().items(joi.string().min(1)).required(),
43
+ });
package/src/dex/index.ts CHANGED
@@ -76,6 +76,7 @@ import { AngleStakedStable } from './angle-staked-stable/angle-staked-stable';
76
76
  import { QuickPerps } from './quick-perps/quick-perps';
77
77
  import { NomiswapV2 } from './uniswap-v2/nomiswap-v2';
78
78
  import { Dexalot } from './dexalot/dexalot';
79
+ import { Bebop } from './bebop/bebop';
79
80
  import { Wombat } from './wombat/wombat';
80
81
  import { Swell } from './swell/swell';
81
82
  import { PharaohV1 } from './solidly/forks-override/pharaohV1';
@@ -110,6 +111,7 @@ const LegacyDexes = [
110
111
  ];
111
112
 
112
113
  const Dexes = [
114
+ Bebop,
113
115
  Dexalot,
114
116
  CurveV1,
115
117
  CurveFork,
@@ -26,8 +26,7 @@ export class WooFiV2PollingPool extends StatefulRpcPoller<
26
26
  poolIdentifier: string,
27
27
  dexHelper: IDexHelper,
28
28
  protected config: DexParams,
29
- // It already includes quoteToken
30
- protected tokens: Token[],
29
+ protected baseTokens: Token[],
31
30
  ) {
32
31
  const callbacks = pollingManagerCbExtractor(
33
32
  StatePollingManager.getInstance(dexHelper),
@@ -50,37 +49,66 @@ export class WooFiV2PollingPool extends StatefulRpcPoller<
50
49
  decodeFunction: uint256ToBigInt,
51
50
  },
52
51
  ] as MultiCallParams<MulticallResultOutputs>[]
53
- ).concat(
54
- this.tokens
55
- .map(t => [
56
- {
57
- target: this.config.wooPPV2Address,
58
- callData: ifaces.PPV2.encodeFunctionData('tokenInfos', [t.address]),
59
- decodeFunction: tokenInfoDecoder,
60
- },
61
- {
62
- target: this.config.wooPPV2Address,
63
- callData: ifaces.PPV2.encodeFunctionData('decimalInfo', [
64
- t.address,
65
- ]),
66
- decodeFunction: decimalInfoDecoder,
67
- },
68
- {
69
- target: this.config.wooOracleV2Address,
70
- callData: ifaces.oracleV2.encodeFunctionData('state', [t.address]),
71
- decodeFunction: stateDecoder,
72
- },
73
- ])
74
- .flat(),
75
- );
52
+ )
53
+ .concat([
54
+ {
55
+ target: this.config.wooPPV2Address,
56
+ callData: ifaces.PPV2.encodeFunctionData('tokenInfos', [
57
+ this.config.quoteToken.address,
58
+ ]),
59
+ decodeFunction: tokenInfoDecoder,
60
+ },
61
+ {
62
+ target: this.config.wooPPV2Address,
63
+ callData: ifaces.PPV2.encodeFunctionData('decimalInfo', [
64
+ this.config.quoteToken.address,
65
+ ]),
66
+ decodeFunction: decimalInfoDecoder,
67
+ },
68
+ ])
69
+ .concat(
70
+ this.baseTokens
71
+ .map(t => [
72
+ {
73
+ target: this.config.wooPPV2Address,
74
+ callData: ifaces.PPV2.encodeFunctionData('tokenInfos', [
75
+ t.address,
76
+ ]),
77
+ decodeFunction: tokenInfoDecoder,
78
+ },
79
+ {
80
+ target: this.config.wooPPV2Address,
81
+ callData: ifaces.PPV2.encodeFunctionData('decimalInfo', [
82
+ t.address,
83
+ ]),
84
+ decodeFunction: decimalInfoDecoder,
85
+ },
86
+ {
87
+ target: this.config.wooOracleV2Address,
88
+ callData: ifaces.oracleV2.encodeFunctionData('state', [
89
+ t.address,
90
+ ]),
91
+ decodeFunction: stateDecoder,
92
+ },
93
+ ])
94
+ .flat(),
95
+ );
76
96
  }
77
97
 
78
98
  protected _parseStateFromMultiResults(
79
99
  multiOutputs: MulticallResultOutputs[],
80
100
  ): PoolState {
81
- const [isPaused, oracleTimestamp, ...remained] = multiOutputs as [
101
+ const [
102
+ isPaused,
103
+ oracleTimestamp,
104
+ quoteTokenInfo,
105
+ quoteTokenDecimals,
106
+ ...remained
107
+ ] = multiOutputs as [
82
108
  boolean,
83
109
  bigint,
110
+ TokenInfo,
111
+ DecimalInfo,
84
112
  ...MulticallResultOutputs[],
85
113
  ];
86
114
 
@@ -88,13 +116,16 @@ export class WooFiV2PollingPool extends StatefulRpcPoller<
88
116
  const decimals: Record<string, DecimalInfo> = {};
89
117
  const tokenStates: Record<string, TokenState> = {};
90
118
 
119
+ tokenInfos[this.config.quoteToken.address] = quoteTokenInfo;
120
+ decimals[this.config.quoteToken.address] = quoteTokenDecimals;
121
+
91
122
  _.chunk(remained, 3).forEach((chunk, i) => {
92
123
  const [tokenInfo, decimalInfo, tokenState] = chunk as [
93
124
  TokenInfo,
94
125
  DecimalInfo,
95
126
  TokenState,
96
127
  ];
97
- const token = this.tokens[i];
128
+ const token = this.baseTokens[i];
98
129
 
99
130
  tokenInfos[token.address] = tokenInfo;
100
131
  decimals[token.address] = decimalInfo;
@@ -27,7 +27,6 @@ import { ethers } from 'ethers';
27
27
  import { addressDecode } from '../../lib/decoders';
28
28
  import { ifaces } from './utils';
29
29
  import { StatePollingManager } from '../../lib/stateful-rpc-poller/state-polling-manager';
30
- import { solidityPack } from 'ethers/lib/utils';
31
30
  import { extractReturnAmountPosition } from '../../executor/utils';
32
31
 
33
32
  export class WooFiV2 extends SimpleExchange implements IDex<WooFiV2Data> {
@@ -521,7 +520,7 @@ export class WooFiV2 extends SimpleExchange implements IDex<WooFiV2Data> {
521
520
  this.getIdentifier(),
522
521
  this.dexHelper,
523
522
  this.config,
524
- Object.values(this.tokenByAddress),
523
+ this.baseTokens,
525
524
  );
526
525
 
527
526
  this.pollingManager.initializeAllPendingPools();
@@ -0,0 +1,126 @@
1
+ import { Logger } from 'log4js';
2
+ import { RequestConfig, Response } from '../../dex-helper/irequest-wrapper';
3
+ import {
4
+ connection as WebSocketConnection,
5
+ client as WebSocketClient,
6
+ } from 'websocket';
7
+
8
+ export class SkippingRequest {
9
+ constructor(public message = '') {}
10
+ }
11
+
12
+ export type RequestInfo<T> = {
13
+ requestFunc?: (
14
+ options: RequestConfig,
15
+ ) => Promise<Response<T> | SkippingRequest>;
16
+ requestOptions: RequestConfig;
17
+ caster: (data: unknown) => T;
18
+ authenticate?: (options: RequestConfig) => RequestConfig;
19
+ excludedFieldsCaching?: string[];
20
+ };
21
+
22
+ export type RequestInfoWithHandler<T> = {
23
+ info: RequestInfo<T>;
24
+ handler: (data: T) => void;
25
+ };
26
+
27
+ export class WebSocketFetcher<T> {
28
+ private requests: RequestInfoWithHandler<T>;
29
+ public lastFetchSucceeded: boolean = false;
30
+ private stop: boolean = true;
31
+ private ws: WebSocketClient = new WebSocketClient();
32
+ private connection: WebSocketConnection | null = null;
33
+
34
+ constructor(requestsInfo: RequestInfoWithHandler<T>, private logger: Logger) {
35
+ this.requests = requestsInfo;
36
+ this.ws.on('connect', this.connected.bind(this));
37
+ this.ws.on('connectFailed', this.connectFailed.bind(this));
38
+ }
39
+
40
+ private connected(connection: WebSocketConnection) {
41
+ this.connection = connection;
42
+ this.logger.info(`Connected to ${this.requests.info.requestOptions.url}`);
43
+ this.connection.on('error', this.onError.bind(this));
44
+ this.connection.on('close', this.onClose.bind(this));
45
+ this.connection.on('message', this.onMessage.bind(this));
46
+ }
47
+
48
+ private connectFailed(error: any) {
49
+ this.logger.error(`Connect Error: ${error.toString()}`);
50
+ }
51
+
52
+ private onClose() {
53
+ this.logger.info(`Connection closed`);
54
+ }
55
+
56
+ private onError(error: any) {
57
+ this.logger.error(`Connection Error: ${error.toString()}`);
58
+ }
59
+
60
+ private onMessage(message: any) {
61
+ if (message.type === 'utf8') {
62
+ const response = JSON.parse(message.utf8Data) as Response<T>;
63
+ const reqInfo = this.requests;
64
+ const info = reqInfo.info;
65
+ const options = reqInfo.info.requestOptions;
66
+ this.logger.debug(`(${options.url}) received new data`);
67
+
68
+ try {
69
+ const parsedData = info.caster(response);
70
+ reqInfo.handler(parsedData);
71
+ } catch (e) {
72
+ this.logger.info(e);
73
+ this.logger.info(
74
+ `(${options.url}) received incorrect data ${JSON.stringify(
75
+ response,
76
+ ).replace(/(?:\r\n|\r|\n)/g, ' ')}`,
77
+ e,
78
+ );
79
+ return;
80
+ }
81
+ }
82
+ }
83
+
84
+ private connect() {
85
+ const authorization =
86
+ this.requests.info.requestOptions.headers!.authorization;
87
+ const name = this.requests.info.requestOptions.headers!.name;
88
+ if (typeof authorization !== 'string') {
89
+ throw new Error('Authorization header is not a string');
90
+ }
91
+ if (typeof name !== 'string') {
92
+ throw new Error('Name header is not a string');
93
+ }
94
+ this.ws.connect(
95
+ this.requests.info.requestOptions.url!,
96
+ undefined,
97
+ undefined,
98
+ {
99
+ Authorization: authorization,
100
+ name: name,
101
+ },
102
+ );
103
+ }
104
+
105
+ startPolling(): void {
106
+ this.stop = false;
107
+ this.connect();
108
+ this.logger.info(
109
+ `Connection started for ${this.requests.info.requestOptions.url}`,
110
+ );
111
+ }
112
+
113
+ stopPolling() {
114
+ if (this.connection) {
115
+ this.connection.close();
116
+ }
117
+ this.stop = true;
118
+ this.logger.info(
119
+ `Connection stopped for ${this.requests.info.requestOptions.url}`,
120
+ );
121
+ }
122
+
123
+ isPolling(): boolean {
124
+ return !this.stop;
125
+ }
126
+ }
package/src/types.ts CHANGED
@@ -304,6 +304,7 @@ export type Config = {
304
304
  uniswapV3EventLoggingSampleRate?: number;
305
305
  swaapV2AuthToken?: string;
306
306
  dexalotAuthToken?: string;
307
+ bebopAuthToken?: string;
307
308
  idleDaoAuthToken?: string;
308
309
  forceRpcFallbackDexs: string[];
309
310
  apiKeyTheGraph: string;