@clonegod/ttd-core 2.0.1

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 (77) hide show
  1. package/README.md +3 -0
  2. package/dist/analyze/index.d.ts +3 -0
  3. package/dist/analyze/index.js +49 -0
  4. package/dist/app_config/app_config.d.ts +15 -0
  5. package/dist/app_config/app_config.js +50 -0
  6. package/dist/app_config/env_args.d.ts +16 -0
  7. package/dist/app_config/env_args.js +28 -0
  8. package/dist/app_config/index.d.ts +2 -0
  9. package/dist/app_config/index.js +18 -0
  10. package/dist/cache/arb_cache.d.ts +80 -0
  11. package/dist/cache/arb_cache.js +1010 -0
  12. package/dist/cache/arb_event_pub.d.ts +14 -0
  13. package/dist/cache/arb_event_pub.js +77 -0
  14. package/dist/cache/arb_event_sub.d.ts +17 -0
  15. package/dist/cache/arb_event_sub.js +166 -0
  16. package/dist/cache/index.d.ts +6 -0
  17. package/dist/cache/index.js +22 -0
  18. package/dist/cache/loading_cache.d.ts +62 -0
  19. package/dist/cache/loading_cache.js +233 -0
  20. package/dist/cache/redis_client.d.ts +3 -0
  21. package/dist/cache/redis_client.js +73 -0
  22. package/dist/cache/redis_cmd.d.ts +14 -0
  23. package/dist/cache/redis_cmd.js +83 -0
  24. package/dist/index.d.ts +216 -0
  25. package/dist/index.js +883 -0
  26. package/dist/market_price/estimate_token_amount.d.ts +4 -0
  27. package/dist/market_price/estimate_token_amount.js +109 -0
  28. package/dist/market_price/index.d.ts +1 -0
  29. package/dist/market_price/index.js +17 -0
  30. package/dist/pool/cache_pool_config.d.ts +2 -0
  31. package/dist/pool/cache_pool_config.js +116 -0
  32. package/dist/pool/index.d.ts +3 -0
  33. package/dist/pool/index.js +19 -0
  34. package/dist/pool/pool_util.d.ts +5 -0
  35. package/dist/pool/pool_util.js +65 -0
  36. package/dist/pool/types.d.ts +20 -0
  37. package/dist/pool/types.js +2 -0
  38. package/dist/quote/index.d.ts +1 -0
  39. package/dist/quote/index.js +17 -0
  40. package/dist/quote/log_quote_price.d.ts +2 -0
  41. package/dist/quote/log_quote_price.js +29 -0
  42. package/dist/quote/on_quote_response.d.ts +3 -0
  43. package/dist/quote/on_quote_response.js +28 -0
  44. package/dist/quote/publish_quote_price.d.ts +3 -0
  45. package/dist/quote/publish_quote_price.js +19 -0
  46. package/dist/quote/to_price_message.d.ts +5 -0
  47. package/dist/quote/to_price_message.js +103 -0
  48. package/dist/test/test_is_empty.d.ts +1 -0
  49. package/dist/test/test_is_empty.js +24 -0
  50. package/dist/test/test_log_level.d.ts +3 -0
  51. package/dist/test/test_log_level.js +29 -0
  52. package/dist/test/test_merge_property.d.ts +1 -0
  53. package/dist/test/test_merge_property.js +21 -0
  54. package/dist/token/cache_token_config.d.ts +2 -0
  55. package/dist/token/cache_token_config.js +68 -0
  56. package/dist/token/fixed_symbol_address.d.ts +2 -0
  57. package/dist/token/fixed_symbol_address.js +26 -0
  58. package/dist/token/index.d.ts +6 -0
  59. package/dist/token/index.js +22 -0
  60. package/dist/token/is_not_arb_token.d.ts +1 -0
  61. package/dist/token/is_not_arb_token.js +24 -0
  62. package/dist/token/price/gecko_terminal.d.ts +2 -0
  63. package/dist/token/price/gecko_terminal.js +69 -0
  64. package/dist/token/price/get_bsc_token_price.d.ts +2 -0
  65. package/dist/token/price/get_bsc_token_price.js +131 -0
  66. package/dist/token/price/get_solana_token_price.d.ts +2 -0
  67. package/dist/token/price/get_solana_token_price.js +17 -0
  68. package/dist/token/price/get_tron_token_price.d.ts +2 -0
  69. package/dist/token/price/get_tron_token_price.js +17 -0
  70. package/dist/token/price/index.d.ts +3 -0
  71. package/dist/token/price/index.js +19 -0
  72. package/dist/token/token_util.d.ts +3 -0
  73. package/dist/token/token_util.js +23 -0
  74. package/dist/token/types.d.ts +29 -0
  75. package/dist/token/types.js +2 -0
  76. package/package.json +47 -0
  77. package/types/index.d.ts +709 -0
@@ -0,0 +1,1010 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.ArbCache = void 0;
16
+ const fs_1 = __importDefault(require("fs"));
17
+ const path_1 = __importDefault(require("path"));
18
+ const index_1 = require("../index");
19
+ class ArbCache {
20
+ constructor(env_args) {
21
+ this.chain_id = env_args.chain_id;
22
+ this.loading_cache = (0, index_1.getLoadingCache)();
23
+ this.redis_cmd = (0, index_1.getRedisCommamd)();
24
+ this.token_list = [];
25
+ this.token_symbol_map = new Map();
26
+ this.token_address_map = new Map();
27
+ this.pool_list = [];
28
+ this.pool_address_map = new Map();
29
+ this.trade_config_list = [];
30
+ this.trade_config_map = new Map();
31
+ }
32
+ init() {
33
+ return __awaiter(this, void 0, void 0, function* () {
34
+ var _a;
35
+ try {
36
+ yield Promise.all([
37
+ this.loading_cache.init(),
38
+ this.redis_cmd.init()
39
+ ]);
40
+ this.redis_event_publisher = (0, index_1.getArbEventPublisher)(this);
41
+ (0, index_1.mkdirSync)(path_1.default.join('config', this.chain_id, 'bak').toLowerCase(), true);
42
+ if (((_a = process.env.APP_NAME) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'config-center') {
43
+ yield this.init_configs();
44
+ }
45
+ }
46
+ catch (err) {
47
+ (0, index_1.log_error)('arb_cache init error!', err);
48
+ throw err;
49
+ }
50
+ });
51
+ }
52
+ init_configs() {
53
+ return __awaiter(this, void 0, void 0, function* () {
54
+ var _a;
55
+ let app_name = process.env.APP_NAME;
56
+ if (((_a = process.env.APP_NAME) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== 'config-center') {
57
+ (0, index_1.log_warn)(`Only config-center can initial config! process.env.APP_NAME=${app_name}, return`);
58
+ return;
59
+ }
60
+ let enable_init_cache = process.env.ENABLE_INIT_CACHE;
61
+ if (!(0, index_1.isTrue)(enable_init_cache)) {
62
+ (0, index_1.log_warn)(`Skip initial config data! process.env.ENABLE_INIT_CACHE=${enable_init_cache}`);
63
+ return;
64
+ }
65
+ (0, index_1.log_trace)(`init cache start`);
66
+ yield this.cache_common_service();
67
+ yield this.cache_token_list();
68
+ yield this.cache_pool_list();
69
+ yield this.cache_trade_group();
70
+ (0, index_1.log_trace)(`init cache finish`);
71
+ });
72
+ }
73
+ get_config_filepath(suffix) {
74
+ let chain_id = this.chain_id.toLowerCase();
75
+ let file_name = `config-${chain_id}-${suffix}`;
76
+ return path_1.default.join('config', chain_id, file_name);
77
+ }
78
+ get_bak_config_filepath(suffix) {
79
+ let chain_id = this.chain_id.toLowerCase();
80
+ let file_name = `config-${chain_id}-${suffix}`;
81
+ let bak_dir = 'bak';
82
+ (0, index_1.mkdirSync)(path_1.default.join('config', chain_id, bak_dir));
83
+ return path_1.default.join('config', chain_id, 'bak', file_name);
84
+ }
85
+ refresh_local_cache_token_list(token_list) {
86
+ this.token_list = token_list;
87
+ this.token_symbol_map.clear();
88
+ this.token_address_map.clear();
89
+ for (let token of token_list) {
90
+ this.token_symbol_map.set(token.symbol, token);
91
+ this.token_address_map.set(token.address, token);
92
+ }
93
+ this.token_list_cache_last_update_time = (0, index_1.getCurDateTime)();
94
+ (0, index_1.log_trace)('refresh_local_cache_token_list, success', {
95
+ token_list_len: this.token_list.length,
96
+ token_symbol_map_size: this.token_symbol_map.size,
97
+ token_address_map_szie: this.token_address_map.size
98
+ });
99
+ }
100
+ refresh_local_cache_pool_list(pool_list) {
101
+ this.pool_list = pool_list;
102
+ this.pool_address_map.clear();
103
+ for (let pool of pool_list) {
104
+ this.pool_address_map.set(pool.pool_address, pool);
105
+ }
106
+ this.pool_list_cahce_last_update_time = (0, index_1.getCurDateTime)();
107
+ (0, index_1.log_trace)('refresh_local_cache_pool_list, success', {
108
+ pool_list_len: this.pool_list.length,
109
+ pool_address_map_size: this.pool_address_map.size
110
+ });
111
+ }
112
+ refresh_local_cache_group_map(trade_config) {
113
+ let group_id = trade_config.group.id;
114
+ let group_id_set_in_env = process.env.GROUP_ID;
115
+ if (group_id_set_in_env && group_id !== group_id_set_in_env) {
116
+ (0, index_1.log_warn)(`skip set trade group in local cache! group_id not match to current trader process:`, {
117
+ group_id_set_in_env,
118
+ group_id
119
+ });
120
+ return;
121
+ }
122
+ let others = this.trade_config_list.filter(e => e.group.id !== group_id);
123
+ others.push(trade_config);
124
+ this.trade_config_list = others;
125
+ this.trade_config_map.set(group_id, trade_config);
126
+ this.trade_config_cache_last_update_time = (0, index_1.getCurDateTime)();
127
+ (0, index_1.log_trace)('refresh_local_cache_group_map, success', { group_id });
128
+ }
129
+ cache_token_list() {
130
+ return __awaiter(this, void 0, void 0, function* () {
131
+ (0, index_1.log_trace)(`cache_token_list, start`);
132
+ let filepath = this.get_config_filepath('token-list.json');
133
+ if (!(0, index_1.file_exists)(filepath)) {
134
+ throw new Error(`cache_token_list failed, config file not exist! filepath=${filepath}`);
135
+ }
136
+ let config = (0, index_1.readFile)(filepath);
137
+ let token_list = config.token_list.filter(e => e.enable);
138
+ for (let token of token_list) {
139
+ let field = token.symbol;
140
+ let value = JSON.stringify(token);
141
+ let result = yield this.loading_cache.hset(this.chain_id, index_1.CACHE_KEY_TYPE.CONFIG_TOKEN_LIST, field, value);
142
+ if (index_1.LOG.debug) {
143
+ (0, index_1.log_trace)(`cache_token_list, symbol=${field}, result: ` + JSON.stringify(result));
144
+ }
145
+ if (token.market_price) {
146
+ this.cache_token_market_price(token, -1);
147
+ }
148
+ }
149
+ this.refresh_local_cache_token_list(token_list);
150
+ let result = yield this.loading_cache.hlen(this.chain_id, index_1.CACHE_KEY_TYPE.CONFIG_TOKEN_LIST);
151
+ (0, index_1.log_trace)(`cache_token_list, end`, result);
152
+ });
153
+ }
154
+ update_token_list(input_token_list) {
155
+ return __awaiter(this, void 0, void 0, function* () {
156
+ (0, index_1.log_trace)(`update_token_list, start`);
157
+ if ((0, index_1.isEmpty)(input_token_list)) {
158
+ (0, index_1.log_warn)(`update_token_list, skip! invalid input: token list is empty!`);
159
+ return;
160
+ }
161
+ let filepath = this.get_config_filepath('token-list.json');
162
+ if (!(0, index_1.file_exists)(filepath)) {
163
+ throw new Error(`update_token_list failed, config file not exist! filepath=${filepath}`);
164
+ }
165
+ let config = (0, index_1.readFile)(filepath);
166
+ for (let token of input_token_list) {
167
+ let others = config.token_list.filter(e => e.symbol.toUpperCase() !== token.symbol.toUpperCase());
168
+ if (token.enable) {
169
+ others.push(token);
170
+ }
171
+ else {
172
+ (0, index_1.log_warn)(`update_token_list, token not enable, delete`, token);
173
+ let field = token.symbol;
174
+ yield this.loading_cache.hdel(this.chain_id, index_1.CACHE_KEY_TYPE.CONFIG_TOKEN_LIST, field);
175
+ }
176
+ others = others.sort((a, b) => a.symbol.localeCompare(b.symbol));
177
+ config.token_list = others;
178
+ }
179
+ (0, index_1.writeFile)(filepath, (0, index_1.to_json_str)(config));
180
+ yield this.cache_token_list();
181
+ (0, index_1.log_trace)(`update_token_list, end. token_list.len=${config.token_list.length}`);
182
+ });
183
+ }
184
+ get_token_list() {
185
+ return __awaiter(this, void 0, void 0, function* () {
186
+ if (!(0, index_1.isEmpty)(this.token_list)) {
187
+ return this.token_list;
188
+ }
189
+ return yield this.get_token_list_no_cache();
190
+ });
191
+ }
192
+ get_token_list_no_cache() {
193
+ return __awaiter(this, void 0, void 0, function* () {
194
+ let token_list = [];
195
+ let res = yield this.loading_cache.hget_all(this.chain_id, index_1.CACHE_KEY_TYPE.CONFIG_TOKEN_LIST);
196
+ let { key, value } = res;
197
+ for (let name of Object.keys(value)) {
198
+ token_list.push(JSON.parse(value[name]));
199
+ }
200
+ (0, index_1.log_warn)(`get_token_list_no_cache, key=${key}, token_list.len=${token_list.length}`);
201
+ this.refresh_local_cache_token_list(token_list);
202
+ return token_list;
203
+ });
204
+ }
205
+ get_one_token_info_by_symbol(symbol) {
206
+ return __awaiter(this, void 0, void 0, function* () {
207
+ let token_info = null;
208
+ if (this.token_symbol_map.has(symbol)) {
209
+ token_info = this.token_symbol_map.get(symbol);
210
+ }
211
+ if (!token_info) {
212
+ let token_list = yield this.get_token_list();
213
+ token_info = token_list.find(e => e.symbol === symbol);
214
+ }
215
+ if (!token_info) {
216
+ throw new Error(`get_one_token_info_by_symbol failed, token not exist! symbol: ${symbol}`);
217
+ }
218
+ return token_info;
219
+ });
220
+ }
221
+ publish_token_change_event() {
222
+ return __awaiter(this, void 0, void 0, function* () {
223
+ yield this.redis_event_publisher.publish_config_change_event({
224
+ event_type: index_1.REDIS_EVENT_TYPE_CONFIG_CHANGE.TOKEN_CONFIG_CHANGE,
225
+ event_time: new Date().getTime()
226
+ });
227
+ });
228
+ }
229
+ cache_pool_list() {
230
+ return __awaiter(this, void 0, void 0, function* () {
231
+ (0, index_1.log_trace)(`cache_pool_list, start`);
232
+ let filepath = this.get_config_filepath('pool-list.json');
233
+ if (!(0, index_1.file_exists)(filepath)) {
234
+ throw new Error(`cache_pool_list failed, config file not exist! filepath=${filepath}`);
235
+ }
236
+ let all_dex_pool = [];
237
+ let config = (0, index_1.readFile)(filepath);
238
+ let token_list = yield this.get_token_list();
239
+ for (let { dex_id, pool_list } of config.dex_list) {
240
+ pool_list = pool_list.filter(e => e.enable);
241
+ (0, index_1.log_trace)(`cache_pool_list`, { dex_id, pool_list_len: pool_list.length });
242
+ for (let pool of pool_list) {
243
+ pool.dex_id = dex_id;
244
+ this.set_pool_token_info(pool, token_list);
245
+ this.set_pool_extra(pool);
246
+ let field = pool.pool_address;
247
+ let value = JSON.stringify(pool);
248
+ let result = yield this.loading_cache.hset(this.chain_id, index_1.CACHE_KEY_TYPE.CONFIG_POOL_LIST, field, value);
249
+ if (index_1.LOG.debug) {
250
+ (0, index_1.log_trace)(`cache_pool_list, pool_address=${pool.pool_address}, result: ` + JSON.stringify(result));
251
+ }
252
+ }
253
+ all_dex_pool.push(...pool_list);
254
+ }
255
+ this.refresh_local_cache_pool_list(all_dex_pool);
256
+ let result = yield this.loading_cache.hlen(this.chain_id, index_1.CACHE_KEY_TYPE.CONFIG_POOL_LIST);
257
+ (0, index_1.log_trace)(`cache_pool_list, end`, result);
258
+ });
259
+ }
260
+ set_pool_token_info(pool, token_info_list) {
261
+ if (index_1.LOG.debug) {
262
+ (0, index_1.log_trace)(`set_pool_token_info`);
263
+ }
264
+ let [token0, token1] = pool.pool_name.split('/');
265
+ pool.tokenA = token_info_list.find(e => e.symbol === token0);
266
+ pool.tokenB = token_info_list.find(e => e.symbol === token1);
267
+ if (!pool.tokenA || !pool.tokenB) {
268
+ (0, index_1.log_warn)('set_pool_token_info failed! tokenA or tokenB not exists!', {
269
+ pool_info: pool,
270
+ token_symbol_list: token_info_list.map(e => e.symbol)
271
+ });
272
+ throw new Error(`set_pool_token_info failed! tokenA or tokenB not exists!`);
273
+ }
274
+ }
275
+ set_pool_extra(pool) {
276
+ if (index_1.LOG.debug) {
277
+ (0, index_1.log_trace)(`update_pool_extra`);
278
+ }
279
+ let { pool_name, quote_token, pair: pair } = pool;
280
+ let is_reverse_token = pool_name.startsWith(quote_token);
281
+ pool.is_reverse_token = is_reverse_token;
282
+ if (!pair) {
283
+ throw new Error(`!!! invalid config: pair is empty! pool_name=${pool_name}`);
284
+ }
285
+ if (is_reverse_token && pool_name === pair) {
286
+ (0, index_1.log_trace)(`Warn: bad pair set in the pool config file, check it!`, {
287
+ pool_name,
288
+ quote_token,
289
+ pair,
290
+ is_reverse_token,
291
+ });
292
+ let [token0, token1] = pool.pool_name.split('/');
293
+ pool.pair = token1 + '/' + token0;
294
+ }
295
+ }
296
+ update_pool_list(input_dex_pool_list) {
297
+ return __awaiter(this, void 0, void 0, function* () {
298
+ (0, index_1.log_trace)(`update_pool_list, start`);
299
+ if ((0, index_1.isEmpty)(input_dex_pool_list)) {
300
+ (0, index_1.log_warn)(`update_pool_list, skip! invalid input: pool list is empty!`);
301
+ return;
302
+ }
303
+ let dex_id_list = input_dex_pool_list.map(e => e.dex_id);
304
+ let dex_id_set = new Set(dex_id_list);
305
+ if (dex_id_set.size != input_dex_pool_list.length) {
306
+ throw new Error(`duplicate dex_id in request data! ${dex_id_list}`);
307
+ }
308
+ let filepath = this.get_config_filepath('pool-list.json');
309
+ if (!(0, index_1.file_exists)(filepath)) {
310
+ throw new Error(`update_pool_list failed, config file not exist! filepath=${filepath}`);
311
+ }
312
+ let config = (0, index_1.readFile)(filepath);
313
+ for (let { dex_id, pool_list } of input_dex_pool_list) {
314
+ let dex_pool_config = config.dex_list.find(e => e.dex_id === dex_id);
315
+ if ((0, index_1.isEmpty)(dex_pool_config)) {
316
+ dex_pool_config = { dex_id, pool_list: [] };
317
+ config.dex_list.push(dex_pool_config);
318
+ }
319
+ for (let pool of pool_list) {
320
+ let others = dex_pool_config.pool_list.filter(e => e.pool_address !== pool.pool_address);
321
+ if (pool.enable) {
322
+ others.push(pool);
323
+ }
324
+ else {
325
+ (0, index_1.log_warn)(`update_pool_list, pool not enable, delete`, pool);
326
+ let field = pool.pool_address;
327
+ yield this.loading_cache.hdel(this.chain_id, index_1.CACHE_KEY_TYPE.CONFIG_POOL_LIST, field);
328
+ }
329
+ others = others.sort((a, b) => a.pool_name.localeCompare(b.pool_name));
330
+ dex_pool_config.pool_list = others;
331
+ }
332
+ }
333
+ (0, index_1.writeFile)(filepath, (0, index_1.to_json_str)(config));
334
+ yield this.cache_pool_list();
335
+ (0, index_1.log_trace)(`update_pool_list, end, dex_list.len=${config.dex_list.length}`);
336
+ });
337
+ }
338
+ get_pool_list_by_pair(pair) {
339
+ return __awaiter(this, void 0, void 0, function* () {
340
+ let pool_list = yield this.get_pool_list();
341
+ return pool_list.filter(e => (0, index_1.isEmpty)(pair) || e.pair === pair);
342
+ });
343
+ }
344
+ get_pool_list() {
345
+ return __awaiter(this, void 0, void 0, function* () {
346
+ if (!(0, index_1.isEmpty)(this.pool_list)) {
347
+ return this.pool_list;
348
+ }
349
+ (0, index_1.log_warn)(`get_pool_list, local cache is empty, try get_pool_list_no_cache...`);
350
+ return yield this.get_pool_list_no_cache();
351
+ });
352
+ }
353
+ get_pool_list_no_cache() {
354
+ return __awaiter(this, void 0, void 0, function* () {
355
+ try {
356
+ let res = yield this.loading_cache.hget_all(this.chain_id, index_1.CACHE_KEY_TYPE.CONFIG_POOL_LIST);
357
+ let { key, value } = res;
358
+ let pool_list = [];
359
+ for (let name of Object.keys(value)) {
360
+ pool_list.push(JSON.parse(value[name]));
361
+ }
362
+ (0, index_1.log_warn)(`get_pool_list_no_cache, key=${key}, pool_list.len=${pool_list.length}`);
363
+ this.refresh_local_cache_pool_list(pool_list);
364
+ return pool_list;
365
+ }
366
+ catch (err) {
367
+ (0, index_1.log_error)('get_pool_list_no_cache error!!!', err);
368
+ throw new Error(`get_pool_list_no_cache error! err=${err.message}`);
369
+ }
370
+ });
371
+ }
372
+ get_one_pool_info(pool_address_1) {
373
+ return __awaiter(this, arguments, void 0, function* (pool_address, refresh_cache_if_not_found = true) {
374
+ let pool_info = null;
375
+ if (this.pool_address_map.has(pool_address)) {
376
+ pool_info = this.pool_address_map.get(pool_address);
377
+ }
378
+ if (!pool_info && refresh_cache_if_not_found) {
379
+ (0, index_1.log_warn)(`get_one_pool_info, from local pool_address_map got: ${pool_info}, try get_pool_list_no_cache...`);
380
+ let pool_list = yield this.get_pool_list_no_cache();
381
+ pool_info = pool_list.find(e => e.pool_address === pool_address);
382
+ }
383
+ if (!pool_info) {
384
+ throw new Error(`get_one_pool_info failed, not exist! pool_address=${pool_address}`);
385
+ }
386
+ return pool_info;
387
+ });
388
+ }
389
+ publish_pool_change_event() {
390
+ return __awaiter(this, void 0, void 0, function* () {
391
+ yield this.redis_event_publisher.publish_config_change_event({
392
+ event_type: index_1.REDIS_EVENT_TYPE_CONFIG_CHANGE.POOL_CONFIG_CHANGE,
393
+ event_time: new Date().getTime()
394
+ });
395
+ });
396
+ }
397
+ get_one_pair(input_pair) {
398
+ return __awaiter(this, void 0, void 0, function* () {
399
+ let pair_list = yield this.get_pair_list(input_pair);
400
+ return pair_list.find(e => e.pair === input_pair);
401
+ });
402
+ }
403
+ get_pair_list() {
404
+ return __awaiter(this, arguments, void 0, function* (input_pair = '') {
405
+ if (index_1.LOG.debug) {
406
+ (0, index_1.log_trace)(`get_pair_list, start`, { input_pair });
407
+ }
408
+ let pair_list = [];
409
+ let pair_set = new Set();
410
+ let pair_price_decimals = new Map();
411
+ let pool_list = yield this.get_pool_list_by_pair(input_pair);
412
+ for (let { pair, quote_price_decimals } of pool_list) {
413
+ pair_set.add(pair);
414
+ if (quote_price_decimals || quote_price_decimals > 0) {
415
+ pair_price_decimals.set(pair, quote_price_decimals);
416
+ }
417
+ }
418
+ for (let pair of pair_set) {
419
+ let [base_symbol, quote_symbol] = pair.split('/');
420
+ let tokenA = yield this.get_one_token_info_by_symbol(base_symbol);
421
+ let tokenB = yield this.get_one_token_info_by_symbol(quote_symbol);
422
+ let price_decimals = pair_price_decimals.get(pair);
423
+ if (!price_decimals || price_decimals <= 0) {
424
+ price_decimals = 12;
425
+ }
426
+ let pool_list = (yield this.get_pool_list_by_pair(pair)).filter(e => e.enable).map(e => e.pool_address);
427
+ pair_list.push({
428
+ pair,
429
+ tokenA,
430
+ tokenB,
431
+ price_decimals,
432
+ pool_list
433
+ });
434
+ }
435
+ pair_list = pair_list.sort((a, b) => a.pair.localeCompare(b.pair));
436
+ if (index_1.LOG.debug) {
437
+ (0, index_1.log_trace)(`get_pair_list, end`, pair_list);
438
+ }
439
+ return pair_list;
440
+ });
441
+ }
442
+ cache_common_service() {
443
+ return __awaiter(this, void 0, void 0, function* () {
444
+ (0, index_1.log_trace)(`cache_common_service, start`);
445
+ let filepath = this.get_config_filepath('common-service.json');
446
+ if (!(0, index_1.file_exists)(filepath)) {
447
+ throw new Error(`cache_common_service failed, config file not exist! filepath=${filepath}`);
448
+ }
449
+ let config = (0, index_1.readFile)(filepath);
450
+ let service_list = [
451
+ {
452
+ name: 'config_center',
453
+ service: config.config_center
454
+ },
455
+ {
456
+ name: 'quote',
457
+ service: config.quote || []
458
+ },
459
+ {
460
+ name: 'orderbook',
461
+ service: config.orderbook
462
+ },
463
+ {
464
+ name: 'trade_proxy',
465
+ service: config.trade_proxy
466
+ },
467
+ ];
468
+ for (let { name, service } of service_list) {
469
+ let field = name;
470
+ let value = JSON.stringify(service);
471
+ let result = yield this.loading_cache.hset(this.chain_id, index_1.CACHE_KEY_TYPE.CONFIG_COMMON_SERVICE, field, value);
472
+ (0, index_1.log_trace)(`cache_common_service, field=${field}, result: ` + JSON.stringify(result));
473
+ }
474
+ (0, index_1.log_trace)(`cache_common_service, end`);
475
+ });
476
+ }
477
+ get_common_service() {
478
+ return __awaiter(this, void 0, void 0, function* () {
479
+ try {
480
+ let res = yield this.loading_cache.hget_all(this.chain_id, index_1.CACHE_KEY_TYPE.CONFIG_COMMON_SERVICE);
481
+ let { key, value } = res;
482
+ if (index_1.LOG.debug) {
483
+ (0, index_1.log_trace)('get_common_service, res=', res);
484
+ }
485
+ let config = JSON.parse('{}');
486
+ for (let name of Object.keys(value)) {
487
+ config[name] = JSON.parse(value[name]);
488
+ }
489
+ return config;
490
+ }
491
+ catch (err) {
492
+ (0, index_1.log_error)('get_common_service error!!!', err);
493
+ throw new Error(`get_common_service error! err=${err.message}`);
494
+ }
495
+ });
496
+ }
497
+ cache_trade_group() {
498
+ return __awaiter(this, arguments, void 0, function* (update_group_id = '') {
499
+ (0, index_1.log_trace)(`cache_trade_service, start`);
500
+ let config_dir = path_1.default.join('config', this.chain_id.toLowerCase());
501
+ let all_files = fs_1.default.readdirSync(config_dir);
502
+ let files = all_files.filter(fname => {
503
+ let fname_lower = fname.toLowerCase();
504
+ let fname_prefix = `config-${this.chain_id}-trade`.toLowerCase();
505
+ if (!(0, index_1.isEmpty)(update_group_id)) {
506
+ fname_prefix = `config-${this.chain_id}-trade-${update_group_id}`.toLowerCase();
507
+ }
508
+ return fname_lower.startsWith(fname_prefix) && fname_lower.indexOf('template') === -1;
509
+ }) || [];
510
+ if ((0, index_1.isEmpty)(files)) {
511
+ (0, index_1.log_trace)(`Files in the directory: ${config_dir} \n []`);
512
+ }
513
+ else {
514
+ (0, index_1.log_trace)(`Files in the directory: ${config_dir}:`, files);
515
+ }
516
+ for (let group_file_name of files) {
517
+ let filepath;
518
+ try {
519
+ filepath = path_1.default.join(config_dir, group_file_name);
520
+ if (!(0, index_1.file_exists)(filepath)) {
521
+ throw new Error(`cache_trade_group failed, config file not exist! filepath=${filepath}`);
522
+ }
523
+ let group_config = (0, index_1.readFile)(filepath);
524
+ let { group } = group_config;
525
+ let { id: group_id } = group;
526
+ (0, index_1.log_trace)(`cache_trade_service, group_id=${group_id}`);
527
+ let value = JSON.stringify(group_config);
528
+ let result = yield this.loading_cache.hset(this.chain_id, index_1.CACHE_KEY_TYPE.CONFIG_TRADE_SERVICE, group_id, value);
529
+ this.refresh_local_cache_group_map(group_config);
530
+ yield this.redis_event_publisher.publish_config_change_event({
531
+ event_type: index_1.REDIS_EVENT_TYPE_CONFIG_CHANGE.GROUP_CONFIG_CHANGE,
532
+ event_time: new Date().getTime(),
533
+ group_id
534
+ });
535
+ (0, index_1.log_trace)(`cache_trade_service, group_id=${group_id}, result: `, result);
536
+ }
537
+ catch (err) {
538
+ (0, index_1.log_error)('cache_trade_service error! file_path=' + filepath, err);
539
+ continue;
540
+ }
541
+ }
542
+ (0, index_1.log_trace)(`cache_trade_service, end`);
543
+ });
544
+ }
545
+ update_trade_group(input_trade_config) {
546
+ return __awaiter(this, void 0, void 0, function* () {
547
+ (0, index_1.log_trace)(`update_trade_service, start`);
548
+ let group_id = input_trade_config === null || input_trade_config === void 0 ? void 0 : input_trade_config.group.id;
549
+ if (!group_id) {
550
+ throw new Error(`update_trade_group failed, invalid input: group id is empty or null!`);
551
+ }
552
+ let filepath = this.get_config_filepath(`trade-${group_id}.json`);
553
+ if (!(0, index_1.file_exists)(filepath)) {
554
+ throw new Error(`update_trade_group failed, config file not exist! filepath=${filepath}`);
555
+ }
556
+ let trade_config = (0, index_1.readFile)(filepath);
557
+ let merge_pairs_map = new Map();
558
+ for (let pair of trade_config.pair_list || []) {
559
+ merge_pairs_map.set(pair.name, pair);
560
+ }
561
+ for (let pair of input_trade_config.pair_list) {
562
+ if (pair.enable) {
563
+ merge_pairs_map.set(pair.name, pair);
564
+ }
565
+ else {
566
+ merge_pairs_map.delete(pair.name);
567
+ (0, index_1.log_warn)(`update_trade_group, pair not enable, delete`, pair);
568
+ }
569
+ }
570
+ let merge_pairs_list = Array.from(merge_pairs_map.values()).sort((a, b) => a.name.localeCompare(b.name));
571
+ input_trade_config.pair_list = merge_pairs_list;
572
+ if (!input_trade_config.group.enable) {
573
+ input_trade_config.pair_list = [];
574
+ }
575
+ (0, index_1.writeFile)(filepath, (0, index_1.to_json_str)(input_trade_config));
576
+ yield this.cache_trade_group(group_id);
577
+ (0, index_1.log_trace)(`update_trade_service, end`);
578
+ });
579
+ }
580
+ get_trade_group_id_list() {
581
+ return __awaiter(this, void 0, void 0, function* () {
582
+ let res = yield this.loading_cache.hkeys(this.chain_id, index_1.CACHE_KEY_TYPE.CONFIG_TRADE_SERVICE);
583
+ if (index_1.LOG.debug) {
584
+ (0, index_1.log_trace)('get_trade_group_id_list, res=', res);
585
+ }
586
+ let { key, value } = res;
587
+ return value;
588
+ });
589
+ }
590
+ get_trade_service_by_group_id(group_id) {
591
+ return __awaiter(this, void 0, void 0, function* () {
592
+ let trade_group_config;
593
+ if (this.trade_config_map.has(group_id)) {
594
+ trade_group_config = this.trade_config_map.get(group_id);
595
+ }
596
+ else {
597
+ trade_group_config = yield this.get_trade_service_by_group_id_no_cache(group_id);
598
+ }
599
+ return (0, index_1.deep_clone)(trade_group_config);
600
+ });
601
+ }
602
+ get_trade_service_by_group_id_no_cache(group_id) {
603
+ return __awaiter(this, void 0, void 0, function* () {
604
+ if ((0, index_1.isEmpty)(group_id)) {
605
+ throw new Error(`get_trade_service_by_group_id_no_cache, invalid group_id=${group_id}, return`);
606
+ }
607
+ (0, index_1.log_info)(`get_trade_service_by_group_id_no_cache, group_id=${group_id}, start`);
608
+ let res = yield this.loading_cache.hget(this.chain_id, index_1.CACHE_KEY_TYPE.CONFIG_TRADE_SERVICE, group_id);
609
+ let { key, field, value } = res;
610
+ let trade_group;
611
+ if (value) {
612
+ trade_group = JSON.parse(value);
613
+ this.refresh_local_cache_group_map(trade_group);
614
+ }
615
+ else {
616
+ throw new Error(`get_trade_service_by_group_id_no_cache, failed! group_id=${group_id}, not exist!`);
617
+ }
618
+ (0, index_1.log_info)(`get_trade_service_by_group_id_no_cache, end`);
619
+ return trade_group;
620
+ });
621
+ }
622
+ create_trade_runtime(chain_id, group_id, dex_id, pair_name) {
623
+ return __awaiter(this, void 0, void 0, function* () {
624
+ var _a;
625
+ let args = { group_id, dex_id, pair_name };
626
+ if ((0, index_1.isEmpty)(chain_id)) {
627
+ throw new Error(`Check chain_id: failed! chain_id is empty or null!!! check .env file`);
628
+ }
629
+ if ((0, index_1.isEmpty)(group_id)) {
630
+ throw new Error(`check failed! invalid input: group_id is empty or null! \n${(0, index_1.to_json_str)(args)}`);
631
+ }
632
+ if ((0, index_1.isEmpty)(pair_name)) {
633
+ throw new Error(`Check pair: failed! pair is empty or null! \n${(0, index_1.to_json_str)(args)}`);
634
+ }
635
+ if (pair_name !== pair_name.toUpperCase()) {
636
+ throw new Error(`Check pair: failed! pair need uppercase!! \n${(0, index_1.to_json_str)(args)}`);
637
+ }
638
+ if ((0, index_1.isEmpty)(dex_id)) {
639
+ throw new Error(`check failed! dex_id is empty or null! \n${(0, index_1.to_json_str)(args)}`);
640
+ }
641
+ let dex_id_list = ((_a = process.env.DEX_ID_LIST) === null || _a === void 0 ? void 0 : _a.split(',')) || [];
642
+ if (!dex_id_list.includes(dex_id)) {
643
+ throw new Error(`check failed! dex_id not support! \n ${(0, index_1.to_json_str)({ dex_id, dex_id_list })}`);
644
+ }
645
+ (0, index_1.log_trace)(`create_trade_runtime, start`, args);
646
+ let wallet = (0, index_1.load_wallet)(group_id, false);
647
+ if ((0, index_1.isEmpty)(wallet.public_key) || (0, index_1.isEmpty)(wallet.private_key)) {
648
+ throw new Error(`wallet public_key or private_key is empty!!! group_id=${group_id}`);
649
+ }
650
+ let trade_config = yield this.get_trade_service_by_group_id(group_id);
651
+ if ((0, index_1.isEmpty)(trade_config)) {
652
+ throw new Error(`no trade config for the group! group_id=${group_id}, trade config=${(0, index_1.to_json_str)(trade_config)}`);
653
+ }
654
+ if ((0, index_1.isEmpty)(trade_config.pair_list)) {
655
+ throw new Error(`no trade pair for the group: pair_list is empty!!! please config atleast one pair, then startup! group_id=${group_id}, trade config=${(0, index_1.to_json_str)(trade_config)}`);
656
+ }
657
+ let pair_config = this.find_pair_in_trade_config(pair_name, trade_config);
658
+ if ((0, index_1.isEmpty)(pair_config)) {
659
+ throw new Error(`Not support pair for the group! pair=${pair_name}, group_id=${group_id}, all support pair: ${JSON.stringify(trade_config.pair_list.map(e => e.name))}`);
660
+ }
661
+ let pair_dex = this.find_pair_dex_in_trade_config(dex_id, pair_config);
662
+ if ((0, index_1.isEmpty)(pair_dex)) {
663
+ throw new Error(`pair not config in this dex! pair=${pair_name}, dex_id=${dex_id}! all support dex_id: ${JSON.stringify(pair_config.dex_list.map(e => e.dex_id))}`);
664
+ }
665
+ let update_settings = (0, index_1.deep_merge_object)(trade_config.settings, pair_config.settings);
666
+ let pool_info_list = [];
667
+ for (let pool_address of pair_dex.pool_list) {
668
+ let pool_info = yield this.get_one_pool_info(pool_address);
669
+ pool_info_list.push(pool_info);
670
+ }
671
+ pair_dex.pool_info_list = pool_info_list;
672
+ let trade_runtime = {
673
+ chain_id,
674
+ dex_id,
675
+ group: trade_config.group,
676
+ wallet,
677
+ pair_name: pair_config.name,
678
+ auto_approve: pair_config.auto_approve,
679
+ pair_dex: pair_dex,
680
+ settings: update_settings
681
+ };
682
+ let _trade_runtime = JSON.parse(JSON.stringify(trade_runtime));
683
+ _trade_runtime.wallet = {
684
+ public_key: trade_runtime.wallet.public_key,
685
+ private_key: '******'
686
+ };
687
+ (0, index_1.new_line)(5);
688
+ setTimeout(() => {
689
+ console.log(`=================================================================================`);
690
+ console.log(`| TRADE GROUP RUNTIME |`);
691
+ console.log(`=================================================================================`);
692
+ console.dir(_trade_runtime, { depth: 4 });
693
+ }, 0);
694
+ (0, index_1.log_trace)(`create_trade_runtime, end`);
695
+ return trade_runtime;
696
+ });
697
+ }
698
+ find_pair_in_trade_config(pair_name, trade_config) {
699
+ return trade_config.pair_list.find(e => e.name === pair_name);
700
+ }
701
+ find_pair_dex_in_trade_config(dex_id, pair_config) {
702
+ let pair_dex_config = pair_config.dex_list.find(e => e.dex_id === dex_id);
703
+ return pair_dex_config;
704
+ }
705
+ cache_token_market_price(token_with_price_1) {
706
+ return __awaiter(this, arguments, void 0, function* (token_with_price, ttl = -1) {
707
+ (0, index_1.log_trace)(`cache_market_price, start`);
708
+ if ((0, index_1.isEmpty)(token_with_price.market_price)) {
709
+ throw new Error(`token market price is null or empty!`);
710
+ }
711
+ let { symbol } = token_with_price;
712
+ let field = (0, index_1.format_symbol_name)(symbol);
713
+ let value = JSON.stringify(token_with_price);
714
+ let result = yield this.loading_cache.hset_ex(this.chain_id, index_1.CACHE_KEY_TYPE.MARKET_TOKEN_PRICE, field, value, ttl);
715
+ (0, index_1.log_trace)('cache_market_price, end', result);
716
+ });
717
+ }
718
+ get_token_market_price(symbol) {
719
+ return __awaiter(this, void 0, void 0, function* () {
720
+ try {
721
+ let id = (0, index_1.format_symbol_name)(symbol);
722
+ let res = yield this.loading_cache.hget(this.chain_id, index_1.CACHE_KEY_TYPE.MARKET_TOKEN_PRICE, id);
723
+ if (index_1.LOG.debug) {
724
+ (0, index_1.log_trace)(`get_token_market_price, symbol=${symbol}, res=`, res);
725
+ }
726
+ let { key, field, value } = res;
727
+ let token_with_price = JSON.parse(value);
728
+ return token_with_price;
729
+ }
730
+ catch (err) {
731
+ (0, index_1.log_error)('get_token_market_price error!!! key expired ???', err);
732
+ throw new Error(`get_token_market_price error! err=${err.message}`);
733
+ }
734
+ });
735
+ }
736
+ cache_price_message(price_msg_1) {
737
+ return __awaiter(this, arguments, void 0, function* (price_msg, ttl = 3600) {
738
+ if (index_1.LOG.debug) {
739
+ (0, index_1.log_trace)(`cache_price_message, ttl=${ttl}, start`);
740
+ }
741
+ let { price_id } = price_msg;
742
+ if (!price_id) {
743
+ throw new Error(`cache_price_message failed! invalid price_id=${price_id}`);
744
+ }
745
+ let field = price_id;
746
+ let value = JSON.stringify(price_msg);
747
+ let result = yield this.loading_cache.hset_ex(this.chain_id, index_1.CACHE_KEY_TYPE.QUOTE_PRICE, field, value, ttl);
748
+ if (index_1.LOG.debug) {
749
+ (0, index_1.log_trace)('cache_price_message, end', result);
750
+ }
751
+ });
752
+ }
753
+ get_price_message(price_id) {
754
+ return __awaiter(this, void 0, void 0, function* () {
755
+ if (!price_id) {
756
+ throw new Error(`get_price_message failed! invalid price_id=${price_id}`);
757
+ }
758
+ let res = yield this.loading_cache.hget(this.chain_id, index_1.CACHE_KEY_TYPE.QUOTE_PRICE, price_id);
759
+ if (index_1.LOG.debug) {
760
+ (0, index_1.log_trace)(`get_price_message, res=`, res);
761
+ }
762
+ let { key, field, value } = res;
763
+ let price_message = JSON.parse(value);
764
+ return price_message;
765
+ });
766
+ }
767
+ cache_order_message(order_msg_1) {
768
+ return __awaiter(this, arguments, void 0, function* (order_msg, ttl = 3600) {
769
+ if (index_1.LOG.debug) {
770
+ (0, index_1.log_trace)(`cache_order_message, ttl=${ttl}, start`);
771
+ }
772
+ let unique_order_msg_id = order_msg.unique_order_msg_id;
773
+ if ((0, index_1.isEmpty)(unique_order_msg_id)) {
774
+ let { group_id, price_id, order_trace_id } = order_msg;
775
+ throw new Error(`cache_order_message failed! unique_order_msg_id cann't null!
776
+ group_id=${group_id}, price_id=${price_id}, order_trace_id=${order_trace_id}`);
777
+ }
778
+ let field = order_msg.unique_order_msg_id;
779
+ let value = JSON.stringify(order_msg);
780
+ let result = yield this.loading_cache.hset_ex(this.chain_id, index_1.CACHE_KEY_TYPE.ORDER_MESSAGE, field, value, ttl);
781
+ if (index_1.LOG.debug) {
782
+ (0, index_1.log_trace)('cache_order_message, end', result);
783
+ }
784
+ return result;
785
+ });
786
+ }
787
+ get_order_message(group_id, price_id, order_trace_id) {
788
+ return __awaiter(this, void 0, void 0, function* () {
789
+ if (!group_id || !price_id || !order_trace_id) {
790
+ throw new Error(`get_order_message failed! invalid params:
791
+ group_id=${group_id}, price_id=${price_id}, trace_id=${order_trace_id}`);
792
+ }
793
+ let _field = (0, index_1.format_unique_order_msg_id)(group_id, price_id, order_trace_id);
794
+ let res = yield this.loading_cache.hget(this.chain_id, index_1.CACHE_KEY_TYPE.ORDER_MESSAGE, _field);
795
+ if (index_1.LOG.debug) {
796
+ (0, index_1.log_trace)(`get_order_message, res=`, res);
797
+ }
798
+ let { key, field, value } = res;
799
+ let order_message = JSON.parse(value);
800
+ return order_message;
801
+ });
802
+ }
803
+ cache_trade_result(trade_result_1) {
804
+ return __awaiter(this, arguments, void 0, function* (trade_result, ttl = 3600) {
805
+ if (index_1.LOG.debug) {
806
+ (0, index_1.log_trace)(`cache_trade_result, ttl=${ttl}, start`);
807
+ }
808
+ let { group_id, txid } = trade_result === null || trade_result === void 0 ? void 0 : trade_result.data;
809
+ if (!group_id && !txid) {
810
+ throw new Error(`cache_trade_result failed! invalid field value: group_id=${group_id}, txid=${txid}`);
811
+ }
812
+ let field = `${group_id}_${txid}`;
813
+ let value = JSON.stringify(trade_result);
814
+ let result = yield this.loading_cache.hset_ex(this.chain_id, index_1.CACHE_KEY_TYPE.ORDER_RESULT, field, value, ttl);
815
+ if (index_1.LOG.debug) {
816
+ (0, index_1.log_trace)('cache_trade_result, end', result);
817
+ }
818
+ return result;
819
+ });
820
+ }
821
+ get_trade_result(group_id, txid) {
822
+ return __awaiter(this, void 0, void 0, function* () {
823
+ if (!group_id || !txid) {
824
+ throw new Error(`get_trade_result failed! invalid params: group_id=${group_id}, txid=${txid}`);
825
+ }
826
+ let _field = `${group_id}_${txid}`;
827
+ let res = yield this.loading_cache.hget(this.chain_id, index_1.CACHE_KEY_TYPE.ORDER_RESULT, _field);
828
+ if (index_1.LOG.debug) {
829
+ (0, index_1.log_trace)(`get_trade_result, res=`, res);
830
+ }
831
+ let { key, field, value } = res;
832
+ let trade_result = JSON.parse(value);
833
+ return trade_result;
834
+ });
835
+ }
836
+ listen_trade_result(event_emitter) {
837
+ this.event_emitter = event_emitter;
838
+ let trade_response;
839
+ this.event_emitter.on(index_1.TRANSACTION_STATE_PROCESSING, (no_trade_result) => __awaiter(this, void 0, void 0, function* () {
840
+ trade_response = {
841
+ code: 100,
842
+ msg: index_1.PROCESSING,
843
+ data: no_trade_result
844
+ };
845
+ yield this.cache_trade_result(trade_response);
846
+ (0, index_1.log_trace)(`listen_trade_result, cache tx status: ${index_1.TRANSACTION_STATE_PROCESSING}`, {
847
+ txid: no_trade_result === null || no_trade_result === void 0 ? void 0 : no_trade_result.txid,
848
+ event: index_1.TRANSACTION_STATE_PROCESSING
849
+ });
850
+ }));
851
+ this.event_emitter.on(index_1.TRANSACTION_STATE_SUCCESS, (success_result) => __awaiter(this, void 0, void 0, function* () {
852
+ let { txid } = success_result;
853
+ trade_response = {
854
+ code: 200,
855
+ msg: index_1.SUCCESS,
856
+ data: success_result
857
+ };
858
+ let { group_id, pair } = success_result;
859
+ this.redis_event_publisher.publish_tx_result_event(group_id, pair, trade_response);
860
+ yield this.cache_trade_result(trade_response);
861
+ (0, index_1.log_trace)(`listen_trade_result, cache tx status: ${index_1.TRANSACTION_STATE_SUCCESS}`, {
862
+ txid: txid,
863
+ event: index_1.TRANSACTION_STATE_SUCCESS
864
+ });
865
+ }));
866
+ this.event_emitter.on(index_1.TRANSACTION_STATE_FAILED, (err_result) => __awaiter(this, void 0, void 0, function* () {
867
+ let { txid, error_code } = err_result;
868
+ trade_response = {
869
+ code: 500,
870
+ msg: index_1.FAILED,
871
+ data: err_result,
872
+ error_code,
873
+ };
874
+ let { group_id, pair } = err_result;
875
+ this.redis_event_publisher.publish_tx_result_event(group_id, pair, trade_response);
876
+ yield this.cache_trade_result(trade_response);
877
+ (0, index_1.log_trace)(`listen_trade_result, cache failed tx status: ${index_1.TRANSACTION_STATE_FAILED}`, {
878
+ txid,
879
+ event: index_1.TRANSACTION_STATE_FAILED
880
+ });
881
+ }));
882
+ }
883
+ get_pair_dex_pool_list(quote_pair_list, dex_id_list) {
884
+ return __awaiter(this, void 0, void 0, function* () {
885
+ let pool_list = [];
886
+ for (let pair of quote_pair_list) {
887
+ let pair_info = yield this.get_one_pair(pair);
888
+ if (!pair_info) {
889
+ continue;
890
+ }
891
+ for (let pool_address of pair_info.pool_list) {
892
+ let pool = yield this.get_one_pool_info(pool_address);
893
+ if (dex_id_list.includes(pool.dex_id)) {
894
+ pool_list.push(pool);
895
+ }
896
+ }
897
+ }
898
+ return pool_list;
899
+ });
900
+ }
901
+ get_trade_dex_pool_list(dex_id_list, trade_runtime) {
902
+ return __awaiter(this, void 0, void 0, function* () {
903
+ let pool_list = [];
904
+ let pair = trade_runtime.pair_name;
905
+ let pair_info = yield this.get_one_pair(pair);
906
+ if (!pair_info) {
907
+ throw new Error(`Invalid pair: ${pair}`);
908
+ }
909
+ for (let pool_address of pair_info.pool_list) {
910
+ let pool = yield this.get_one_pool_info(pool_address);
911
+ if (dex_id_list.includes(pool.dex_id)) {
912
+ pool_list.push(pool);
913
+ }
914
+ }
915
+ return pool_list;
916
+ });
917
+ }
918
+ get_group_trade_pair_info(chain_id, group_id, pair) {
919
+ return __awaiter(this, void 0, void 0, function* () {
920
+ if (!chain_id || !group_id) {
921
+ throw new Error(`get_group_trade_pair_info fail! invalid params: chain_id=${chain_id}, group_id=${group_id}, pair=${pair}`);
922
+ }
923
+ const pair_map = new Map();
924
+ let trade_group_conifg = yield this.get_trade_service_by_group_id(group_id);
925
+ let { pair_list } = trade_group_conifg;
926
+ let pair_names = pair_list.filter(e => (0, index_1.isEmpty)(pair) || e.name === pair).map(e => e.name);
927
+ let trade_group_pool_id_list = [];
928
+ for (let trade_pair of pair_list) {
929
+ for (let dex of trade_pair.dex_list) {
930
+ trade_group_pool_id_list.push(...dex.pool_list);
931
+ }
932
+ }
933
+ for (let pair_name of pair_names) {
934
+ let pair_info = yield this.get_one_pair(pair_name);
935
+ if (!pair_info) {
936
+ (0, index_1.log_warn)(`not found pair info!!!`, { chain_id, group_id, pair });
937
+ }
938
+ else {
939
+ let unique_orderbook_id_list = [];
940
+ for (let _pool_address of pair_info.pool_list.filter(e => trade_group_pool_id_list.includes(e))) {
941
+ let { dex_id, pool_address, fee_rate } = yield this.get_one_pool_info(_pool_address);
942
+ unique_orderbook_id_list.push((0, index_1.format_unique_orderbook_id)(chain_id, dex_id, pool_address, fee_rate));
943
+ }
944
+ pair_info.pool_list = unique_orderbook_id_list;
945
+ pair_map.set(pair_name, pair_info);
946
+ }
947
+ }
948
+ return pair_map;
949
+ });
950
+ }
951
+ get_all_trade_tokens() {
952
+ return __awaiter(this, void 0, void 0, function* () {
953
+ let token_address_set = new Set();
954
+ let group_id_list = yield this.get_trade_group_id_list();
955
+ for (let group_id of group_id_list) {
956
+ let trade_group_conifg = yield this.get_trade_service_by_group_id(group_id);
957
+ let { pair_list } = trade_group_conifg;
958
+ let trade_group_pool_id_list = [];
959
+ for (let trade_pair of pair_list) {
960
+ for (let dex of trade_pair.dex_list) {
961
+ trade_group_pool_id_list.push(...dex.pool_list);
962
+ }
963
+ }
964
+ for (let pool_id of trade_group_pool_id_list) {
965
+ try {
966
+ let { tokenA, tokenB } = yield this.get_one_pool_info(pool_id);
967
+ token_address_set.add(tokenA.address);
968
+ token_address_set.add(tokenB.address);
969
+ }
970
+ catch (err) {
971
+ (0, index_1.log_warn)(`get_all_trade_tokens error: ${err.message}`);
972
+ }
973
+ }
974
+ }
975
+ let token_list = [];
976
+ for (let token_address of token_address_set) {
977
+ token_list.push(this.token_address_map.get(token_address));
978
+ }
979
+ return token_list;
980
+ });
981
+ }
982
+ get_all_trade_pools() {
983
+ return __awaiter(this, arguments, void 0, function* (group_id = '') {
984
+ let pools = [];
985
+ let group_id_list = yield this.get_trade_group_id_list();
986
+ group_id_list = group_id_list.filter(gid => (0, index_1.isEmpty)(group_id) || gid === group_id);
987
+ for (let group_id of group_id_list) {
988
+ let trade_group_conifg = yield this.get_trade_service_by_group_id(group_id);
989
+ let { pair_list } = trade_group_conifg;
990
+ let trade_group_pool_id_list = [];
991
+ for (let trade_pair of pair_list) {
992
+ for (let dex of trade_pair.dex_list) {
993
+ trade_group_pool_id_list.push(...dex.pool_list);
994
+ }
995
+ }
996
+ for (let pool_id of trade_group_pool_id_list) {
997
+ try {
998
+ let pool = yield this.get_one_pool_info(pool_id);
999
+ pools.push(pool);
1000
+ }
1001
+ catch (err) {
1002
+ (0, index_1.log_warn)(`get_all_trade_pools error: ${err.message}`);
1003
+ }
1004
+ }
1005
+ }
1006
+ return pools;
1007
+ });
1008
+ }
1009
+ }
1010
+ exports.ArbCache = ArbCache;