@clonegod/ttd-base-common 1.0.26 → 1.1.2

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 (144) hide show
  1. package/dist/appconfig/BaseQuoteAppConfig.d.ts +10 -0
  2. package/dist/appconfig/BaseQuoteAppConfig.js +36 -0
  3. package/dist/appconfig/BaseTradeAppConfig.d.ts +7 -0
  4. package/dist/appconfig/BaseTradeAppConfig.js +13 -0
  5. package/dist/appconfig/base_dex_env_args.d.ts +5 -0
  6. package/dist/appconfig/base_dex_env_args.js +68 -0
  7. package/dist/appconfig/base_env_args.d.ts +82 -0
  8. package/dist/appconfig/base_env_args.js +91 -0
  9. package/dist/appconfig/ensure_core_env.d.ts +1 -0
  10. package/dist/appconfig/ensure_core_env.js +18 -0
  11. package/dist/appconfig/index.d.ts +5 -0
  12. package/dist/appconfig/index.js +21 -0
  13. package/dist/index.d.ts +2 -2
  14. package/dist/index.js +2 -2
  15. package/dist/quote/depth/amm_depth_calculator.d.ts +19 -0
  16. package/dist/quote/depth/amm_depth_calculator.js +55 -0
  17. package/dist/quote/depth/clmm_depth_calculator.d.ts +28 -0
  18. package/dist/quote/depth/clmm_depth_calculator.js +176 -0
  19. package/dist/quote/depth/index.d.ts +51 -0
  20. package/dist/quote/depth/index.js +264 -0
  21. package/dist/quote/depth/tick_liquidity_snapshot.d.ts +58 -0
  22. package/dist/quote/depth/tick_liquidity_snapshot.js +143 -0
  23. package/dist/quote/event/index.d.ts +1 -0
  24. package/dist/quote/event/index.js +1 -0
  25. package/dist/quote/event/pool_event_listener.d.ts +5 -3
  26. package/dist/quote/event/pool_event_listener.js +128 -150
  27. package/dist/quote/event/swap_debouncer.d.ts +22 -0
  28. package/dist/quote/event/swap_debouncer.js +80 -0
  29. package/dist/quote/get_base_token_price.d.ts +6 -0
  30. package/dist/quote/get_base_token_price.js +90 -0
  31. package/dist/quote/index.d.ts +7 -0
  32. package/dist/quote/index.js +7 -0
  33. package/dist/quote/preload_token_prices.d.ts +2 -0
  34. package/dist/quote/preload_token_prices.js +37 -0
  35. package/dist/quote/price_feed_handler.d.ts +15 -0
  36. package/dist/quote/price_feed_handler.js +56 -0
  37. package/dist/quote/pricing/fee_helpers.d.ts +13 -0
  38. package/dist/quote/pricing/fee_helpers.js +68 -0
  39. package/dist/quote/pricing/index.d.ts +3 -1
  40. package/dist/quote/pricing/index.js +3 -1
  41. package/dist/quote/pricing/pool_state_initializer.d.ts +12 -0
  42. package/dist/quote/pricing/pool_state_initializer.js +191 -0
  43. package/dist/quote/pricing/sdk_token_factory.d.ts +2 -0
  44. package/dist/quote/pricing/sdk_token_factory.js +21 -0
  45. package/dist/quote/quote_amount.d.ts +4 -0
  46. package/dist/quote/quote_amount.js +24 -0
  47. package/dist/quote/tick/cached_tick_data_provider.d.ts +12 -0
  48. package/dist/quote/tick/cached_tick_data_provider.js +45 -0
  49. package/dist/quote/tick/clmm_tick_cache.d.ts +42 -0
  50. package/dist/quote/tick/clmm_tick_cache.js +236 -0
  51. package/dist/quote/tick/index.d.ts +4 -0
  52. package/dist/{ws → quote/tick}/index.js +4 -2
  53. package/dist/quote/tick/state_view_tick_loader.d.ts +17 -0
  54. package/dist/quote/tick/state_view_tick_loader.js +136 -0
  55. package/dist/quote/tick/tick_lens_loaders.d.ts +24 -0
  56. package/dist/quote/tick/tick_lens_loaders.js +158 -0
  57. package/dist/quote/verify/index.d.ts +2 -0
  58. package/dist/quote/verify/index.js +5 -0
  59. package/dist/quote/verify/quote_price_verify.d.ts +30 -0
  60. package/dist/quote/verify/quote_price_verify.js +240 -0
  61. package/dist/redis/redis_client.d.ts +3 -2
  62. package/dist/redis/redis_client.js +86 -116
  63. package/dist/send-tx/constants.d.ts +2 -0
  64. package/dist/send-tx/constants.js +6 -0
  65. package/dist/send-tx/index.d.ts +2 -0
  66. package/dist/{config → send-tx}/index.js +2 -1
  67. package/dist/send-tx/types.d.ts +4 -0
  68. package/dist/send-tx/types.js +2 -0
  69. package/dist/trade/abstract_dex_trade.d.ts +43 -21
  70. package/dist/trade/abstract_dex_trade.js +347 -133
  71. package/dist/trade/caller_manager.d.ts +31 -0
  72. package/dist/trade/caller_manager.js +202 -0
  73. package/dist/trade/check/abstract_tx_result_checker.d.ts +28 -0
  74. package/dist/trade/check/abstract_tx_result_checker.js +192 -0
  75. package/dist/trade/check/index.d.ts +1 -1
  76. package/dist/trade/check/index.js +1 -1
  77. package/dist/trade/index.d.ts +2 -2
  78. package/dist/trade/index.js +2 -2
  79. package/dist/trade/parse/base_parser.d.ts +1 -2
  80. package/dist/trade/parse/base_parser.js +36 -36
  81. package/dist/trade/trade_trace.d.ts +17 -0
  82. package/dist/trade/trade_trace.js +65 -0
  83. package/dist/types/config_types.d.ts +3 -3
  84. package/dist/types/event_types.d.ts +3 -3
  85. package/dist/types/pool_state.d.ts +140 -13
  86. package/dist/utils/ethers_compat.d.ts +13 -0
  87. package/dist/utils/ethers_compat.js +18 -0
  88. package/dist/utils/fast_signer.d.ts +1 -0
  89. package/dist/utils/fast_signer.js +87 -0
  90. package/dist/utils/gas_helper.d.ts +2 -2
  91. package/dist/utils/gas_helper.js +48 -60
  92. package/dist/utils/index.d.ts +5 -2
  93. package/dist/utils/index.js +6 -2
  94. package/dist/utils/pool_filter.d.ts +8 -0
  95. package/dist/utils/pool_filter.js +38 -0
  96. package/dist/utils/trade_direction.d.ts +14 -0
  97. package/dist/utils/trade_direction.js +23 -0
  98. package/package.json +3 -3
  99. package/dist/config/base_env_args.d.ts +0 -11
  100. package/dist/config/base_env_args.js +0 -19
  101. package/dist/config/index.d.ts +0 -1
  102. package/dist/quote/event/verify_clmm_swap_event.d.ts +0 -1
  103. package/dist/quote/event/verify_clmm_swap_event.js +0 -178
  104. package/dist/quote/pricing/token_price_cache.d.ts +0 -10
  105. package/dist/quote/pricing/token_price_cache.js +0 -40
  106. package/dist/trade/abstract_dex_trade_plus.d.ts +0 -43
  107. package/dist/trade/abstract_dex_trade_plus.js +0 -421
  108. package/dist/trade/check/tx_websocket_manager.d.ts +0 -23
  109. package/dist/trade/check/tx_websocket_manager.js +0 -119
  110. package/dist/trade/send/alchemy_base.d.ts +0 -5
  111. package/dist/trade/send/alchemy_base.js +0 -48
  112. package/dist/trade/send/ankr_base.d.ts +0 -5
  113. package/dist/trade/send/ankr_base.js +0 -48
  114. package/dist/trade/send/base_rpc.d.ts +0 -5
  115. package/dist/trade/send/base_rpc.js +0 -48
  116. package/dist/trade/send/blockpi_base.d.ts +0 -5
  117. package/dist/trade/send/blockpi_base.js +0 -48
  118. package/dist/trade/send/bloxroute_base.d.ts +0 -11
  119. package/dist/trade/send/bloxroute_base.js +0 -115
  120. package/dist/trade/send/chainstack_base.d.ts +0 -5
  121. package/dist/trade/send/chainstack_base.js +0 -48
  122. package/dist/trade/send/drpc_base.d.ts +0 -5
  123. package/dist/trade/send/drpc_base.js +0 -48
  124. package/dist/trade/send/getblock_base.d.ts +0 -5
  125. package/dist/trade/send/getblock_base.js +0 -48
  126. package/dist/trade/send/index.d.ts +0 -15
  127. package/dist/trade/send/index.js +0 -33
  128. package/dist/trade/send/infura_base.d.ts +0 -5
  129. package/dist/trade/send/infura_base.js +0 -48
  130. package/dist/trade/send/moralis_base.d.ts +0 -5
  131. package/dist/trade/send/moralis_base.js +0 -48
  132. package/dist/trade/send/onerpc_base.d.ts +0 -5
  133. package/dist/trade/send/onerpc_base.js +0 -48
  134. package/dist/trade/send/quicknode_base.d.ts +0 -5
  135. package/dist/trade/send/quicknode_base.js +0 -48
  136. package/dist/trade/send/send_tx.d.ts +0 -17
  137. package/dist/trade/send/send_tx.js +0 -163
  138. package/dist/ws/event_filter.d.ts +0 -8
  139. package/dist/ws/event_filter.js +0 -36
  140. package/dist/ws/index.d.ts +0 -2
  141. package/dist/ws/subscribe_v2_events.d.ts +0 -14
  142. package/dist/ws/subscribe_v2_events.js +0 -174
  143. package/dist/ws/subscribe_v3_events.d.ts +0 -14
  144. package/dist/ws/subscribe_v3_events.js +0 -174
@@ -0,0 +1,240 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QuotePriceVerify = void 0;
4
+ const trade_direction_1 = require("../../utils/trade_direction");
5
+ const ttd_core_1 = require("@clonegod/ttd-core");
6
+ function pickMatchingTier(tiers, actualAmountIn) {
7
+ if (!tiers || tiers.length === 0)
8
+ return null;
9
+ if (tiers.length === 1)
10
+ return { tier: tiers[0], mode: 'single_tier' };
11
+ const sorted = [...tiers].sort((a, b) => a.amount_in - b.amount_in);
12
+ const top = sorted[sorted.length - 1];
13
+ if (actualAmountIn < sorted[0].amount_in) {
14
+ return { tier: sorted[0], mode: 'extrapolated_low' };
15
+ }
16
+ if (actualAmountIn > top.amount_in) {
17
+ return { tier: top, mode: 'extrapolated_high' };
18
+ }
19
+ for (let i = 0; i < sorted.length - 1; i++) {
20
+ const lower = sorted[i];
21
+ const upper = sorted[i + 1];
22
+ if (actualAmountIn >= lower.amount_in && actualAmountIn <= upper.amount_in) {
23
+ if (actualAmountIn === lower.amount_in)
24
+ return { tier: lower, mode: 'exact' };
25
+ if (actualAmountIn === upper.amount_in)
26
+ return { tier: upper, mode: 'exact' };
27
+ const span = upper.amount_in - lower.amount_in;
28
+ if (span <= 0)
29
+ return { tier: lower, mode: 'exact' };
30
+ const ratio = (actualAmountIn - lower.amount_in) / span;
31
+ const lerp = (a, b) => a + ratio * (b - a);
32
+ return {
33
+ tier: {
34
+ pct: lerp(lower.pct, upper.pct),
35
+ price: lerp(lower.price, upper.price),
36
+ amount: lerp(lower.amount, upper.amount),
37
+ amount_in: actualAmountIn,
38
+ amount_in_usd: lerp(lower.amount_in_usd, upper.amount_in_usd),
39
+ fee: lerp(lower.fee, upper.fee),
40
+ fee_usd: lerp(lower.fee_usd, upper.fee_usd),
41
+ },
42
+ mode: 'interpolated',
43
+ };
44
+ }
45
+ }
46
+ return { tier: top, mode: 'extrapolated_high' };
47
+ }
48
+ class QuotePriceVerify {
49
+ constructor() {
50
+ this.quoteCache = new Map();
51
+ }
52
+ get enabled() {
53
+ return process.env.VERIFY_QUOTE_PRICE === 'true';
54
+ }
55
+ cacheQuote(poolAddress, priceId, source, askPrice, bidPrice, blockNumber, quoteAmountUsd, token0PriceUsd = 0, token1PriceUsd = 0, tiers) {
56
+ if (!this.enabled)
57
+ return;
58
+ if (!source)
59
+ return;
60
+ let sourceMap = this.quoteCache.get(poolAddress);
61
+ if (!sourceMap) {
62
+ sourceMap = new Map();
63
+ this.quoteCache.set(poolAddress, sourceMap);
64
+ }
65
+ const existing = sourceMap.get(source);
66
+ const verifiedReferenceBlock = (existing && existing.referenceBlock === blockNumber)
67
+ ? existing.verifiedReferenceBlock
68
+ : 0;
69
+ sourceMap.set(source, {
70
+ priceId, source, askPrice, bidPrice,
71
+ askTiers: tiers?.askTiers,
72
+ bidTiers: tiers?.bidTiers,
73
+ referenceBlock: blockNumber,
74
+ verifiedReferenceBlock,
75
+ quoteAmountUsd,
76
+ token0PriceUsd, token1PriceUsd,
77
+ });
78
+ }
79
+ checkSwap(params) {
80
+ if (!this.enabled)
81
+ return;
82
+ const { poolAddress, blockNumber, txHash, poolInfo, token0Address } = params;
83
+ const sourceMap = this.quoteCache.get(poolAddress);
84
+ if (!sourceMap || sourceMap.size === 0)
85
+ return;
86
+ const swapData = this.deriveSwapDirection(params);
87
+ if (!swapData)
88
+ return;
89
+ const direction = (0, trade_direction_1.resolveTradeDirection)(poolInfo, true);
90
+ const inputIsQuoteToken = swapData.inputTokenAddress.toLowerCase() === direction.quoteToken.address.toLowerCase();
91
+ const isBuy = inputIsQuoteToken;
92
+ const execPriceStr = (0, trade_direction_1.calculateStandardPrice)(swapData.inputAmountUi, swapData.outputAmountUi, isBuy);
93
+ const execPrice = Number(execPriceStr);
94
+ if (execPrice <= 0)
95
+ return;
96
+ const verifiable = [];
97
+ for (const [source, cached] of sourceMap) {
98
+ if (blockNumber <= cached.referenceBlock)
99
+ continue;
100
+ if (cached.verifiedReferenceBlock === cached.referenceBlock)
101
+ continue;
102
+ const tiers = isBuy ? cached.askTiers : cached.bidTiers;
103
+ let refPrice;
104
+ let tierInfo;
105
+ if (tiers && tiers.length > 0) {
106
+ const match = pickMatchingTier(tiers, swapData.inputAmountUi);
107
+ if (!match)
108
+ continue;
109
+ refPrice = match.tier.price;
110
+ tierInfo = {
111
+ matched_pct: parseFloat(match.tier.pct.toFixed(4)),
112
+ mode: match.mode,
113
+ tier_amount_in: match.tier.amount_in,
114
+ };
115
+ }
116
+ else {
117
+ refPrice = isBuy ? cached.askPrice : cached.bidPrice;
118
+ }
119
+ if (refPrice <= 0)
120
+ continue;
121
+ cached.verifiedReferenceBlock = cached.referenceBlock;
122
+ const diff_bps = (refPrice - execPrice) / refPrice * 10000;
123
+ verifiable.push({ source, cached, refPrice, diff_bps, tierInfo });
124
+ }
125
+ if (verifiable.length === 0)
126
+ return;
127
+ verifiable.sort((a, b) => b.cached.referenceBlock - a.cached.referenceBlock);
128
+ const primary = verifiable[0];
129
+ const sources = {};
130
+ for (const r of verifiable) {
131
+ sources[r.source] = {
132
+ ask: r.cached.askPrice,
133
+ bid: r.cached.bidPrice,
134
+ diff_bps: parseFloat(r.diff_bps.toFixed(1)),
135
+ quote_block: r.cached.referenceBlock,
136
+ ...(r.tierInfo && {
137
+ matched_pct: r.tierInfo.matched_pct,
138
+ tier_mode: r.tierInfo.mode,
139
+ tier_amount_in: r.tierInfo.tier_amount_in,
140
+ }),
141
+ };
142
+ }
143
+ this.compareAndLog(poolAddress, params.poolName, poolInfo, primary.cached, swapData.inputTokenAddress, swapData.outputTokenAddress, swapData.inputAmountUi, swapData.outputAmountUi, primary.refPrice, execPrice, primary.cached.token0PriceUsd, primary.cached.token1PriceUsd, token0Address, blockNumber, txHash, sources, primary.tierInfo);
144
+ }
145
+ deriveSwapDirection(params) {
146
+ const { amount0, amount1, token0Address, token1Address, token0Decimals, token1Decimals } = params;
147
+ const sign = params.swapperDeltaConvention ? -1n : 1n;
148
+ const amt0 = BigInt(amount0) * sign;
149
+ const amt1 = BigInt(amount1) * sign;
150
+ if (amt0 === 0n && amt1 === 0n)
151
+ return null;
152
+ if (amt0 > 0n && amt1 < 0n) {
153
+ return {
154
+ inputTokenAddress: token0Address,
155
+ outputTokenAddress: token1Address,
156
+ inputAmountUi: Number(amt0) / Math.pow(10, token0Decimals),
157
+ outputAmountUi: Number(-amt1) / Math.pow(10, token1Decimals),
158
+ };
159
+ }
160
+ else if (amt0 < 0n && amt1 > 0n) {
161
+ return {
162
+ inputTokenAddress: token1Address,
163
+ outputTokenAddress: token0Address,
164
+ inputAmountUi: Number(amt1) / Math.pow(10, token1Decimals),
165
+ outputAmountUi: Number(-amt0) / Math.pow(10, token0Decimals),
166
+ };
167
+ }
168
+ return null;
169
+ }
170
+ compareAndLog(poolAddress, poolName, poolInfo, cached, inputTokenAddress, outputTokenAddress, inputAmountUi, outputAmountUi, refPrice, execPriceNum, token0PriceUsd, token1PriceUsd, token0Address, swapBlockNumber, txHash, sources, primaryTierInfo) {
171
+ if (inputAmountUi <= 0 || outputAmountUi <= 0)
172
+ return;
173
+ let swapUsd = 0;
174
+ if (token0PriceUsd && token1PriceUsd && token0Address) {
175
+ const inputIsToken0 = inputTokenAddress.toLowerCase() === token0Address.toLowerCase();
176
+ swapUsd = inputIsToken0
177
+ ? inputAmountUi * token0PriceUsd
178
+ : inputAmountUi * token1PriceUsd;
179
+ }
180
+ const direction = (0, trade_direction_1.resolveTradeDirection)(poolInfo, true);
181
+ const baseToken = direction.baseToken;
182
+ const quoteToken = direction.quoteToken;
183
+ const inputIsQuoteToken = inputTokenAddress.toLowerCase() === quoteToken.address.toLowerCase();
184
+ const isBuy = inputIsQuoteToken;
185
+ const side = isBuy ? 'BUY' : 'SELL';
186
+ if (refPrice <= 0 || execPriceNum <= 0)
187
+ return;
188
+ const diffBps = (refPrice - execPriceNum) / refPrice * 10000;
189
+ const absDiffBps = Math.abs(diffBps);
190
+ const status = absDiffBps < 5 ? '✅' : absDiffBps < 10 ? '⚠️' : '❌';
191
+ const usdStr = swapUsd > 0 ? `$${swapUsd.toFixed(0)}` : '$?';
192
+ const maxUsd = cached.quoteAmountUsd * 2;
193
+ const inRange = swapUsd <= 0 || swapUsd <= maxUsd;
194
+ const rangeTag = inRange ? '' : ' [out]';
195
+ const tradeFlow = isBuy
196
+ ? `${inputAmountUi.toFixed(4)} ${quoteToken.symbol} -> ${outputAmountUi.toFixed(4)} ${baseToken.symbol}`
197
+ : `${inputAmountUi.toFixed(4)} ${baseToken.symbol} -> ${outputAmountUi.toFixed(4)} ${quoteToken.symbol}`;
198
+ const quoteSrc = cached.source || '?';
199
+ const quoteTag = `quote[${quoteSrc} blk:${cached.referenceBlock}]`;
200
+ const swapBlk = swapBlockNumber || '?';
201
+ const swapTx = txHash ? ` ${txHash.slice(0, 10)}` : '';
202
+ const swapTag = `swap[blk:${swapBlk}${swapTx}]`;
203
+ const priceLabel = isBuy ? 'ask' : 'bid';
204
+ const msg = ` ↳ [Verify] ${side} ${usdStr} (${tradeFlow}) ${quoteTag} ${priceLabel}=${refPrice.toFixed(12)} vs ${swapTag} exec=${execPriceNum.toFixed(12)} diff=${diffBps > 0 ? '+' : ''}${diffBps.toFixed(1)}bps ${status}${rangeTag}`;
205
+ (0, ttd_core_1.log_info)(msg);
206
+ try {
207
+ (0, ttd_core_1.report_data_to_analyze)('QuoteVerify', {
208
+ pool_address: poolAddress,
209
+ pool_name: poolName,
210
+ price_id: cached.priceId,
211
+ source: cached.source,
212
+ quote_amount_usd: cached.quoteAmountUsd,
213
+ quote_block: cached.referenceBlock,
214
+ swap_block: swapBlockNumber,
215
+ tx_hash: txHash || '',
216
+ side,
217
+ ref_price: refPrice,
218
+ exec_price: execPriceNum,
219
+ diff_bps: parseFloat(diffBps.toFixed(1)),
220
+ swap_usd: parseFloat(swapUsd.toFixed(0)),
221
+ in_range: inRange,
222
+ input_amount: inputAmountUi,
223
+ output_amount: outputAmountUi,
224
+ input_symbol: isBuy ? quoteToken.symbol : baseToken.symbol,
225
+ output_symbol: isBuy ? baseToken.symbol : quoteToken.symbol,
226
+ status,
227
+ time: Date.now(),
228
+ sources: sources || undefined,
229
+ ...(primaryTierInfo && {
230
+ matched_tier_pct: primaryTierInfo.matched_pct,
231
+ matched_tier_mode: primaryTierInfo.mode,
232
+ matched_tier_amount_in: primaryTierInfo.tier_amount_in,
233
+ }),
234
+ });
235
+ }
236
+ catch (_) {
237
+ }
238
+ }
239
+ }
240
+ exports.QuotePriceVerify = QuotePriceVerify;
@@ -1,4 +1,4 @@
1
- import { RedisClientType } from "redis";
1
+ type RedisAny = any;
2
2
  export declare class SimpleRedisClient {
3
3
  private lock_prefix;
4
4
  private redisClient;
@@ -6,7 +6,7 @@ export declare class SimpleRedisClient {
6
6
  private lockRetryDelayMs;
7
7
  private lockExpireSeconds;
8
8
  constructor(lock_prefix: string);
9
- getRedisClient(): Promise<RedisClientType>;
9
+ getRedisClient(): Promise<RedisAny>;
10
10
  private getLockKey;
11
11
  acquireLock(lock_key: string, lock_value: string, expireSeconds?: number): Promise<boolean>;
12
12
  releaseLock(lock_key: string, lock_value: string): Promise<boolean>;
@@ -19,3 +19,4 @@ export declare class SimpleRedisClient {
19
19
  hgetall(key: string): Promise<any>;
20
20
  del(key: string, field?: string): Promise<any>;
21
21
  }
22
+ export {};
@@ -1,16 +1,8 @@
1
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
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.SimpleRedisClient = void 0;
13
4
  const dist_1 = require("@clonegod/ttd-core/dist");
5
+ const redis_connection_1 = require("@clonegod/ttd-core/dist/redis/redis_connection");
14
6
  class SimpleRedisClient {
15
7
  constructor(lock_prefix) {
16
8
  this.lock_prefix = lock_prefix;
@@ -19,137 +11,115 @@ class SimpleRedisClient {
19
11
  this.lockRetryDelayMs = 300;
20
12
  this.lockExpireSeconds = 3;
21
13
  }
22
- getRedisClient() {
23
- return __awaiter(this, void 0, void 0, function* () {
24
- if (!this.redisClient) {
25
- this.redisClient = yield (0, dist_1.getRedisCache)();
26
- }
27
- return this.redisClient;
28
- });
14
+ async getRedisClient() {
15
+ if (!this.redisClient) {
16
+ this.redisClient = await (0, redis_connection_1.getRedisConnection)();
17
+ }
18
+ return this.redisClient;
29
19
  }
30
20
  getLockKey(lock_identifier) {
31
21
  return `${this.lock_prefix}:lock:${lock_identifier}`;
32
22
  }
33
- acquireLock(lock_key_1, lock_value_1) {
34
- return __awaiter(this, arguments, void 0, function* (lock_key, lock_value, expireSeconds = this.lockExpireSeconds) {
35
- const redisClient = yield this.getRedisClient();
36
- const result = yield redisClient.set(lock_key, lock_value, {
37
- NX: true,
38
- EX: expireSeconds
39
- });
40
- (0, dist_1.log_info)(`try acquireLock: lock_key=${lock_key}, lock_value=${lock_value}, expireSeconds=${expireSeconds}, result=${result}`);
41
- const success = result === 'OK';
42
- if (success) {
43
- (0, dist_1.log_info)(`acquire lock success: lock_key=${lock_key}, lock_value=${lock_value}`);
44
- }
45
- return success;
23
+ async acquireLock(lock_key, lock_value, expireSeconds = this.lockExpireSeconds) {
24
+ const redisClient = await this.getRedisClient();
25
+ const result = await redisClient.set(lock_key, lock_value, {
26
+ NX: true,
27
+ EX: expireSeconds
46
28
  });
29
+ (0, dist_1.log_info)(`try acquireLock: lock_key=${lock_key}, lock_value=${lock_value}, expireSeconds=${expireSeconds}, result=${result}`);
30
+ const success = result === 'OK';
31
+ if (success) {
32
+ (0, dist_1.log_info)(`acquire lock success: lock_key=${lock_key}, lock_value=${lock_value}`);
33
+ }
34
+ return success;
47
35
  }
48
- releaseLock(lock_key, lock_value) {
49
- return __awaiter(this, void 0, void 0, function* () {
50
- const redisClient = yield this.getRedisClient();
51
- const script = `
36
+ async releaseLock(lock_key, lock_value) {
37
+ const redisClient = await this.getRedisClient();
38
+ const script = `
52
39
  if redis.call('get', KEYS[1]) == ARGV[1] then
53
40
  return redis.call('del', KEYS[1])
54
41
  else
55
42
  return 0
56
43
  end
57
44
  `;
58
- const result = yield redisClient.eval(script, {
59
- keys: [lock_key],
60
- arguments: [lock_value]
61
- });
62
- const success = Number(result) === 1;
63
- if (success) {
64
- (0, dist_1.log_info)(`release lock success: lock_key=${lock_key}, lock_value=${lock_value}`);
65
- }
66
- else {
67
- (0, dist_1.log_info)(`release lock failed: lock_key=${lock_key}, lock_value=${lock_value}, maybe expired or locked by other process`);
68
- }
69
- return success;
45
+ const result = await redisClient.eval(script, {
46
+ keys: [lock_key],
47
+ arguments: [lock_value]
70
48
  });
49
+ const success = Number(result) === 1;
50
+ if (success) {
51
+ (0, dist_1.log_info)(`release lock success: lock_key=${lock_key}, lock_value=${lock_value}`);
52
+ }
53
+ else {
54
+ (0, dist_1.log_info)(`release lock failed: lock_key=${lock_key}, lock_value=${lock_value}, maybe expired or locked by other process`);
55
+ }
56
+ return success;
71
57
  }
72
- withLock(lock_identifier_1, callback_1) {
73
- return __awaiter(this, arguments, void 0, function* (lock_identifier, callback, release_lock_delay_ms = 2000) {
74
- const lock_key = this.getLockKey(lock_identifier);
75
- const lock_value = `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
76
- let retries = 0;
77
- let acquired = false;
78
- let first_try_time = Date.now();
79
- let get_lock_time = 0;
80
- try {
81
- while (retries < this.lockMaxRetries) {
82
- acquired = yield this.acquireLock(lock_key, lock_value);
83
- if (acquired)
84
- break;
85
- yield new Promise(resolve => setTimeout(resolve, this.lockRetryDelayMs));
86
- retries++;
87
- }
88
- if (acquired) {
89
- get_lock_time = Date.now();
90
- return yield callback();
91
- }
58
+ async withLock(lock_identifier, callback, release_lock_delay_ms = 2000) {
59
+ const lock_key = this.getLockKey(lock_identifier);
60
+ const lock_value = `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
61
+ let retries = 0;
62
+ let acquired = false;
63
+ let first_try_time = Date.now();
64
+ let get_lock_time = 0;
65
+ try {
66
+ while (retries < this.lockMaxRetries) {
67
+ acquired = await this.acquireLock(lock_key, lock_value);
68
+ if (acquired)
69
+ break;
70
+ await new Promise(resolve => setTimeout(resolve, this.lockRetryDelayMs));
71
+ retries++;
92
72
  }
93
- finally {
94
- if (acquired) {
95
- const release_delay = parseInt(process.env.NONCE_LOCK_RELEASE_DELAY_MS || String(release_lock_delay_ms));
96
- yield (0, dist_1.sleep)(release_delay);
97
- yield this.releaseLock(lock_key, lock_value);
98
- (0, dist_1.log_info)(`withLock success: lock_key=${lock_key}, lock_value=${lock_value}, retry times=${retries}, get lock take ${get_lock_time - first_try_time}ms, release_delay=${release_delay}ms, hold lock ${Date.now() - get_lock_time}ms`);
99
- }
100
- else {
101
- (0, dist_1.log_warn)(`withLock failed: lock_key=${lock_key}, lock_value=${lock_value}, retry times=${retries}, took ${Date.now() - first_try_time}ms`);
102
- }
73
+ if (acquired) {
74
+ get_lock_time = Date.now();
75
+ return await callback();
103
76
  }
104
- });
77
+ }
78
+ finally {
79
+ if (acquired) {
80
+ const release_delay = parseInt(process.env.NONCE_LOCK_RELEASE_DELAY_MS || String(release_lock_delay_ms));
81
+ await (0, dist_1.sleep)(release_delay);
82
+ await this.releaseLock(lock_key, lock_value);
83
+ (0, dist_1.log_info)(`withLock success: lock_key=${lock_key}, lock_value=${lock_value}, retry times=${retries}, get lock take ${get_lock_time - first_try_time}ms, release_delay=${release_delay}ms, hold lock ${Date.now() - get_lock_time}ms`);
84
+ }
85
+ else {
86
+ (0, dist_1.log_warn)(`withLock failed: lock_key=${lock_key}, lock_value=${lock_value}, retry times=${retries}, took ${Date.now() - first_try_time}ms`);
87
+ }
88
+ }
105
89
  }
106
- getValue(key) {
107
- return __awaiter(this, void 0, void 0, function* () {
108
- const redisClient = yield this.getRedisClient();
109
- return yield redisClient.get(key);
110
- });
90
+ async getValue(key) {
91
+ const redisClient = await this.getRedisClient();
92
+ return await redisClient.get(key);
111
93
  }
112
- setValue(key, value, expireSeconds) {
113
- return __awaiter(this, void 0, void 0, function* () {
114
- const redisClient = yield this.getRedisClient();
115
- return yield redisClient.set(key, value, {
116
- EX: expireSeconds
117
- });
94
+ async setValue(key, value, expireSeconds) {
95
+ const redisClient = await this.getRedisClient();
96
+ return await redisClient.set(key, value, {
97
+ EX: expireSeconds
118
98
  });
119
99
  }
120
- hsetValue(key, field, value, expireSeconds) {
121
- return __awaiter(this, void 0, void 0, function* () {
122
- const redisClient = yield this.getRedisClient();
123
- yield redisClient.hSet(key, field, value);
124
- yield redisClient.hExpire(key, field, expireSeconds);
125
- });
100
+ async hsetValue(key, field, value, expireSeconds) {
101
+ const redisClient = await this.getRedisClient();
102
+ await redisClient.hSet(key, field, value);
103
+ await redisClient.hExpire(key, field, expireSeconds);
126
104
  }
127
- hgetvalue(key, field) {
128
- return __awaiter(this, void 0, void 0, function* () {
129
- const redisClient = yield this.getRedisClient();
130
- return yield redisClient.hGet(key, field);
131
- });
105
+ async hgetvalue(key, field) {
106
+ const redisClient = await this.getRedisClient();
107
+ return await redisClient.hGet(key, field);
132
108
  }
133
- hkeys(key) {
134
- return __awaiter(this, void 0, void 0, function* () {
135
- const redisClient = yield this.getRedisClient();
136
- return yield redisClient.hKeys(key);
137
- });
109
+ async hkeys(key) {
110
+ const redisClient = await this.getRedisClient();
111
+ return await redisClient.hKeys(key);
138
112
  }
139
- hgetall(key) {
140
- return __awaiter(this, void 0, void 0, function* () {
141
- const redisClient = yield this.getRedisClient();
142
- return yield redisClient.hGetAll(key);
143
- });
113
+ async hgetall(key) {
114
+ const redisClient = await this.getRedisClient();
115
+ return await redisClient.hGetAll(key);
144
116
  }
145
- del(key_1) {
146
- return __awaiter(this, arguments, void 0, function* (key, field = '') {
147
- const redisClient = yield this.getRedisClient();
148
- if (field) {
149
- return yield redisClient.hDel(key, field);
150
- }
151
- return yield redisClient.del(key);
152
- });
117
+ async del(key, field = '') {
118
+ const redisClient = await this.getRedisClient();
119
+ if (field) {
120
+ return await redisClient.hDel(key, field);
121
+ }
122
+ return await redisClient.del(key);
153
123
  }
154
124
  }
155
125
  exports.SimpleRedisClient = SimpleRedisClient;
@@ -0,0 +1,2 @@
1
+ export declare enum BASE_EOA_ADDRESS {
2
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BASE_EOA_ADDRESS = void 0;
4
+ var BASE_EOA_ADDRESS;
5
+ (function (BASE_EOA_ADDRESS) {
6
+ })(BASE_EOA_ADDRESS || (exports.BASE_EOA_ADDRESS = BASE_EOA_ADDRESS = {}));
@@ -0,0 +1,2 @@
1
+ export * from './types';
2
+ export * from './constants';
@@ -14,4 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./base_env_args"), exports);
17
+ __exportStar(require("./types"), exports);
18
+ __exportStar(require("./constants"), exports);
@@ -0,0 +1,4 @@
1
+ import { TradeTrace } from '../trade/trade_trace';
2
+ export interface ITransactionSender {
3
+ sendTransaction(signedMainTx: string, tipTxMap: Map<string, string>, order_trace_id: string, pair?: string, only_bundle?: boolean, trace?: Pick<TradeTrace, 'mark'>): Promise<string[]>;
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,27 +1,49 @@
1
- import { AbastrcatTrade, AppConfig, TradeContext } from "@clonegod/ttd-core/dist";
1
+ import { AbastrcatTrade, AppConfig, TradeContext, EvmGasArgs } from '@clonegod/ttd-core';
2
+ import { BaseEnvArgs } from '../appconfig/base_env_args';
2
3
  import { ethers } from "ethers";
3
- import { DexConfig, EvmChainConfig } from "../types";
4
- export declare abstract class AbstractEvmDexTrade extends AbastrcatTrade {
4
+ import { EvmChainConfig } from "../types";
5
+ import { CallerManager } from "./caller_manager";
6
+ import { ITransactionSender } from "../send-tx";
7
+ import { RedisClient } from "@clonegod/ttd-core";
8
+ export interface TradeConfig {
9
+ vaultAddress: string;
10
+ executorIds: Record<string, string>;
11
+ }
12
+ export declare function buildTradeConfig(envArgs: BaseEnvArgs): TradeConfig;
13
+ export interface TradeCalldata {
14
+ executorId: string;
15
+ data: string;
16
+ }
17
+ export declare abstract class AbstractDexTrade extends AbastrcatTrade {
5
18
  protected appConfig: AppConfig;
6
- protected wallet: ethers.Wallet;
7
- protected provider: ethers.providers.JsonRpcProvider;
8
- protected approvedTokens: Map<string, boolean>;
9
- protected pairContracts: Map<string, ethers.Contract>;
10
- protected tokenContracts: Map<string, ethers.Contract>;
11
- protected routerContract: ethers.Contract;
19
+ protected callerManager: CallerManager;
20
+ protected provider: any;
21
+ protected transactionSender: ITransactionSender;
12
22
  protected chainConfig: EvmChainConfig;
13
- protected dexConfig: DexConfig;
23
+ protected redisClient: RedisClient;
24
+ protected tradeConfig: TradeConfig;
25
+ protected vaultInterface: any;
26
+ protected chainNameLower: string;
14
27
  constructor(appConfig: AppConfig);
15
- protected abstract initConfigs(): void;
16
- init(): Promise<void>;
17
- protected getTokenContract(tokenAddress: string): ethers.Contract;
18
- protected getGasPriceGwei(context: TradeContext): string;
28
+ protected initConfigs(): void;
29
+ abstract encodeTradeData(context: TradeContext): TradeCalldata;
30
+ init(transactionSender?: ITransactionSender): Promise<void>;
31
+ execute(context: TradeContext): Promise<string>;
32
+ private scanCallerFiles;
33
+ protected computeEvmGasArgs(context: TradeContext): EvmGasArgs;
34
+ protected gasArgsToMainFields(args: EvmGasArgs): any;
35
+ protected buildGasFields(context: TradeContext): {
36
+ mainGasFields: any;
37
+ tipGasPriceGwei: string;
38
+ };
39
+ protected getGasLimit(context: TradeContext): number;
40
+ protected getLegacyGasPriceGwei(context: TradeContext): string;
19
41
  protected getBuilderTipAmoutGwei(context: TradeContext): string;
20
- protected checkTradeTokenApprove(context: TradeContext, routerAddress?: string): Promise<void>;
21
- protected checkTokenApprove(tokenAddress: string, tokenSymbol: string, tokenContract: ethers.Contract, spenderAddress: string): Promise<boolean>;
22
- protected isNonceRelatedError(error: any): boolean;
23
- protected isNativeCurrency(symbol: string): boolean;
24
- protected getWrappedNativeAddress(): string;
25
- abstract execute(context: TradeContext, retryCount?: number): Promise<string>;
26
- protected buildTipTransferTx(to: string, transfer_amount_gwei: string, gas_price_gwei: string, transfer_nonce: number): Promise<string>;
42
+ protected buildTipTransferTx(to: string, transfer_amount_gwei: string, gas_price_gwei: string, nonce: number, wallet: ethers.Wallet): Promise<string>;
43
+ protected determineInputOutputTokens(order_msg: any, pool_info: any): {
44
+ inputToken: any;
45
+ outputToken: any;
46
+ };
47
+ protected calculateAmountOutMin(context: TradeContext, _inputToken: any, outputToken: any): ethers.BigNumber;
48
+ private extractNonceFromErrorMsg;
27
49
  }