@clonegod/ttd-sui-common 1.0.101 → 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 (126) hide show
  1. package/dist/appconfig/SuiQuoteAppConfig.d.ts +10 -0
  2. package/dist/appconfig/SuiQuoteAppConfig.js +35 -0
  3. package/dist/appconfig/SuiTradeAppConfig.d.ts +7 -0
  4. package/dist/appconfig/SuiTradeAppConfig.js +13 -0
  5. package/dist/appconfig/ensure_core_env.d.ts +1 -0
  6. package/dist/appconfig/ensure_core_env.js +18 -0
  7. package/dist/appconfig/index.d.ts +5 -0
  8. package/dist/appconfig/index.js +21 -0
  9. package/dist/appconfig/sui_dex_env_args.d.ts +5 -0
  10. package/dist/appconfig/sui_dex_env_args.js +28 -0
  11. package/dist/appconfig/sui_env_args.d.ts +4 -0
  12. package/dist/appconfig/sui_env_args.js +20 -0
  13. package/dist/grpc/gas-price-cache.js +19 -32
  14. package/dist/grpc/grpc-connection.js +5 -3
  15. package/dist/grpc/grpc_provider_registry.d.ts +14 -0
  16. package/dist/grpc/grpc_provider_registry.js +60 -0
  17. package/dist/grpc/index.d.ts +3 -0
  18. package/dist/grpc/index.js +13 -1
  19. package/dist/grpc/ledger-service.js +107 -128
  20. package/dist/grpc/proto_value.d.ts +4 -0
  21. package/dist/grpc/proto_value.js +59 -0
  22. package/dist/grpc/state-service.d.ts +1 -0
  23. package/dist/grpc/state-service.js +99 -102
  24. package/dist/grpc/sui-grpc-client.js +2 -13
  25. package/dist/grpc/sui_object_reader.d.ts +15 -0
  26. package/dist/grpc/sui_object_reader.js +60 -0
  27. package/dist/grpc/transaction-service.js +26 -37
  28. package/dist/index.d.ts +1 -1
  29. package/dist/index.js +1 -1
  30. package/dist/quote/abstract_dex_quote.d.ts +60 -0
  31. package/dist/quote/abstract_dex_quote.js +186 -0
  32. package/dist/quote/chain_ops.d.ts +17 -0
  33. package/dist/quote/chain_ops.js +52 -0
  34. package/dist/quote/index.d.ts +7 -0
  35. package/dist/quote/index.js +7 -0
  36. package/dist/quote/pool_event.d.ts +21 -0
  37. package/dist/quote/pool_event.js +6 -0
  38. package/dist/quote/pricing/token_price_cache.js +18 -29
  39. package/dist/quote/quote_amount.d.ts +4 -0
  40. package/dist/quote/quote_amount.js +24 -0
  41. package/dist/quote/quote_trace.d.ts +16 -0
  42. package/dist/quote/quote_trace.js +40 -0
  43. package/dist/quote/tick/clmm_v3_engine.d.ts +32 -0
  44. package/dist/quote/tick/clmm_v3_engine.js +48 -0
  45. package/dist/quote/tick/index.d.ts +4 -0
  46. package/dist/quote/tick/index.js +20 -0
  47. package/dist/quote/tick/local_clmm_state.d.ts +17 -0
  48. package/dist/quote/tick/local_clmm_state.js +22 -0
  49. package/dist/quote/tick/sui_clmm_tick_cache.d.ts +42 -0
  50. package/dist/quote/tick/sui_clmm_tick_cache.js +163 -0
  51. package/dist/quote/tick/sui_tick_data_provider.d.ts +2 -0
  52. package/dist/quote/tick/sui_tick_data_provider.js +6 -0
  53. package/dist/quote/verify/index.d.ts +1 -0
  54. package/dist/quote/verify/index.js +17 -0
  55. package/dist/quote/verify/quote_price_verify.d.ts +30 -0
  56. package/dist/quote/verify/quote_price_verify.js +247 -0
  57. package/dist/redis/redis_client.d.ts +1 -0
  58. package/dist/redis/redis_client.js +88 -117
  59. package/dist/rpc/index.js +59 -75
  60. package/dist/test/test.js +1 -1
  61. package/dist/test/test_checkpoint.js +4 -13
  62. package/dist/test/test_grpc.js +32 -41
  63. package/dist/trade/abstract_sui_dex_trade.d.ts +43 -0
  64. package/dist/trade/abstract_sui_dex_trade.js +380 -0
  65. package/dist/trade/abstract_sui_dex_trade_plus.d.ts +3 -1
  66. package/dist/trade/abstract_sui_dex_trade_plus.js +232 -212
  67. package/dist/trade/check/tx_result_checker.js +65 -75
  68. package/dist/trade/coin/index.d.ts +1 -0
  69. package/dist/trade/coin/index.js +17 -0
  70. package/dist/trade/coin/lua_scripts.d.ts +5 -0
  71. package/dist/trade/coin/lua_scripts.js +130 -0
  72. package/dist/trade/coin/types.d.ts +30 -0
  73. package/dist/trade/coin/types.js +2 -0
  74. package/dist/trade/coin/wallet_coin_ledger.d.ts +22 -0
  75. package/dist/trade/coin/wallet_coin_ledger.js +85 -0
  76. package/dist/trade/executor/central_executor.d.ts +72 -0
  77. package/dist/trade/executor/central_executor.js +240 -0
  78. package/dist/trade/executor/coin_cache.d.ts +21 -0
  79. package/dist/trade/executor/coin_cache.js +143 -0
  80. package/dist/trade/executor/coin_maintainer.d.ts +32 -0
  81. package/dist/trade/executor/coin_maintainer.js +123 -0
  82. package/dist/trade/executor/core_channel.d.ts +38 -0
  83. package/dist/trade/executor/core_channel.js +131 -0
  84. package/dist/trade/executor/data_channel.d.ts +27 -0
  85. package/dist/trade/executor/data_channel.js +2 -0
  86. package/dist/trade/executor/effects.d.ts +16 -0
  87. package/dist/trade/executor/effects.js +63 -0
  88. package/dist/trade/executor/executor_client.d.ts +13 -0
  89. package/dist/trade/executor/executor_client.js +55 -0
  90. package/dist/trade/executor/executor_protocol.d.ts +26 -0
  91. package/dist/trade/executor/executor_protocol.js +32 -0
  92. package/dist/trade/executor/executor_server.d.ts +8 -0
  93. package/dist/trade/executor/executor_server.js +33 -0
  94. package/dist/trade/executor/executor_ws_client.d.ts +13 -0
  95. package/dist/trade/executor/executor_ws_client.js +58 -0
  96. package/dist/trade/executor/grpc_channel.d.ts +14 -0
  97. package/dist/trade/executor/grpc_channel.js +73 -0
  98. package/dist/trade/executor/index.d.ts +7 -0
  99. package/dist/trade/executor/index.js +23 -0
  100. package/dist/trade/executor/json_rpc_channel.d.ts +14 -0
  101. package/dist/trade/executor/json_rpc_channel.js +77 -0
  102. package/dist/trade/index.d.ts +5 -1
  103. package/dist/trade/index.js +5 -1
  104. package/dist/trade/parse/sui_tx_parser.js +98 -81
  105. package/dist/trade/send_tx/index.js +34 -47
  106. package/dist/trade/swap/builders/bluefin.d.ts +9 -0
  107. package/dist/trade/swap/builders/bluefin.js +60 -0
  108. package/dist/trade/swap/builders/cetus_magma.d.ts +13 -0
  109. package/dist/trade/swap/builders/cetus_magma.js +52 -0
  110. package/dist/trade/swap/builders/momentum.d.ts +9 -0
  111. package/dist/trade/swap/builders/momentum.js +80 -0
  112. package/dist/trade/swap/dex_swap_config.d.ts +28 -0
  113. package/dist/trade/swap/dex_swap_config.js +40 -0
  114. package/dist/trade/swap/index.d.ts +7 -0
  115. package/dist/trade/swap/index.js +36 -0
  116. package/dist/trade/swap/types.d.ts +20 -0
  117. package/dist/trade/swap/types.js +2 -0
  118. package/dist/trade/test/test_parse_sui_tx_result.js +33 -44
  119. package/dist/trade/tx_result_channel.d.ts +7 -0
  120. package/dist/trade/tx_result_channel.js +7 -0
  121. package/dist/utils/decode.js +1 -2
  122. package/dist/utils/index.d.ts +1 -0
  123. package/dist/utils/index.js +1 -0
  124. package/dist/utils/trade_direction.d.ts +14 -0
  125. package/dist/utils/trade_direction.js +23 -0
  126. package/package.json +3 -2
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QuoteTrace = void 0;
4
+ const ttd_core_1 = require("@clonegod/ttd-core");
5
+ const logger = (0, ttd_core_1.createLogger)(__filename);
6
+ class QuoteTrace {
7
+ constructor(poolName, poolAddress, blockNumber = 0, source = '') {
8
+ this.poolName = poolName;
9
+ this.poolAddress = poolAddress;
10
+ this.blockNumber = blockNumber;
11
+ this.source = source;
12
+ this.startTime = Date.now();
13
+ this.marks = [];
14
+ this.data = {};
15
+ this.error = null;
16
+ }
17
+ mark(name) {
18
+ this.marks.push({ name, elapsed: Date.now() - this.startTime });
19
+ }
20
+ set(key, value) { this.data[key] = value; }
21
+ markError(stage, message) { this.error = { stage, message }; }
22
+ buildTimeline() {
23
+ if (this.marks.length === 0)
24
+ return '(no marks)';
25
+ let prev = 0;
26
+ const parts = this.marks.map(m => { const d = m.elapsed - prev; prev = m.elapsed; return `${m.name}(${d}ms)`; });
27
+ return `${parts.join(' -> ')} = ${this.marks[this.marks.length - 1].elapsed}ms`;
28
+ }
29
+ flush() {
30
+ const timeline = this.buildTimeline();
31
+ if (this.error) {
32
+ logger.error(`[QUOTE FAILED] ${this.poolName} | stage=${this.error.stage} | source=${this.source} | ${this.error.message}`, new Error(this.error.message));
33
+ logger.info(`[QUOTE FAILED detail] ${this.poolName}`, { timeline, error_stage: this.error.stage, source: this.source, ...this.data });
34
+ }
35
+ else {
36
+ logger.debug(`[QUOTE OK] ${this.poolName} blk=${this.blockNumber} source=${this.source}`, { timeline, ...this.data });
37
+ }
38
+ }
39
+ }
40
+ exports.QuoteTrace = QuoteTrace;
@@ -0,0 +1,32 @@
1
+ import BN from 'bn.js';
2
+ export type ComputeSwapStepFn = (currentSqrtPrice: BN, targetSqrtPrice: BN, liquidity: BN, amount: BN, feeRate: BN, byAmountIn: boolean) => {
3
+ amountIn: BN;
4
+ amountOut: BN;
5
+ nextSqrtPrice: BN;
6
+ feeAmount: BN;
7
+ };
8
+ export interface V3StepMath {
9
+ computeSwapStep: ComputeSwapStepFn;
10
+ minSqrtPrice: BN;
11
+ maxSqrtPrice: BN;
12
+ }
13
+ export interface V3PoolState {
14
+ currentSqrtPrice: BN;
15
+ currentTickIndex: number;
16
+ liquidity: BN;
17
+ feeRate: BN;
18
+ }
19
+ export interface V3Tick {
20
+ index: number;
21
+ sqrtPrice: BN;
22
+ liquidityNet: BN;
23
+ }
24
+ export interface V3SwapResult {
25
+ amountIn: BN;
26
+ amountOut: BN;
27
+ feeAmount: BN;
28
+ endSqrtPrice: BN;
29
+ isExceed: boolean;
30
+ crossTickNum: number;
31
+ }
32
+ export declare function computeSwapV3(aToB: boolean, byAmountIn: boolean, amount: BN, pool: V3PoolState, ticks: V3Tick[], math: V3StepMath): V3SwapResult;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.computeSwapV3 = computeSwapV3;
7
+ const bn_js_1 = __importDefault(require("bn.js"));
8
+ const ZERO = new bn_js_1.default(0);
9
+ function computeSwapV3(aToB, byAmountIn, amount, pool, ticks, math) {
10
+ const sorted = ticks.slice().sort((a, b) => aToB ? b.index - a.index : a.index - b.index);
11
+ const limit = aToB ? math.minSqrtPrice : math.maxSqrtPrice;
12
+ let remainer = amount;
13
+ let liq = pool.liquidity;
14
+ let curSqrt = pool.currentSqrtPrice;
15
+ let amountIn = ZERO, amountOut = ZERO, feeAmount = ZERO, crossTickNum = 0;
16
+ for (const tick of sorted) {
17
+ if (aToB && pool.currentTickIndex < tick.index)
18
+ continue;
19
+ if (!aToB && pool.currentTickIndex >= tick.index)
20
+ continue;
21
+ const target = (aToB && limit.gt(tick.sqrtPrice)) || (!aToB && limit.lt(tick.sqrtPrice)) ? limit : tick.sqrtPrice;
22
+ const step = math.computeSwapStep(curSqrt, target, liq, remainer, pool.feeRate, byAmountIn);
23
+ if (!step.amountIn.eq(ZERO)) {
24
+ remainer = byAmountIn ? remainer.sub(step.amountIn.add(step.feeAmount)) : remainer.sub(step.amountOut);
25
+ }
26
+ amountIn = amountIn.add(step.amountIn);
27
+ amountOut = amountOut.add(step.amountOut);
28
+ feeAmount = feeAmount.add(step.feeAmount);
29
+ if (step.nextSqrtPrice.eq(tick.sqrtPrice)) {
30
+ liq = aToB ? liq.sub(tick.liquidityNet) : liq.add(tick.liquidityNet);
31
+ curSqrt = tick.sqrtPrice;
32
+ }
33
+ else {
34
+ curSqrt = step.nextSqrtPrice;
35
+ }
36
+ crossTickNum++;
37
+ if (remainer.eq(ZERO))
38
+ break;
39
+ }
40
+ return {
41
+ amountIn: amountIn.add(feeAmount),
42
+ amountOut,
43
+ feeAmount,
44
+ endSqrtPrice: curSqrt,
45
+ isExceed: remainer.gt(ZERO),
46
+ crossTickNum,
47
+ };
48
+ }
@@ -0,0 +1,4 @@
1
+ export * from './local_clmm_state';
2
+ export * from './sui_clmm_tick_cache';
3
+ export * from './sui_tick_data_provider';
4
+ export * from './clmm_v3_engine';
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./local_clmm_state"), exports);
18
+ __exportStar(require("./sui_clmm_tick_cache"), exports);
19
+ __exportStar(require("./sui_tick_data_provider"), exports);
20
+ __exportStar(require("./clmm_v3_engine"), exports);
@@ -0,0 +1,17 @@
1
+ export interface LocalClmmState {
2
+ poolAddress: string;
3
+ coinTypeA: string;
4
+ coinTypeB: string;
5
+ feeRate: number;
6
+ tickSpacing: number;
7
+ currentSqrtPrice: string;
8
+ currentTickIndex: number;
9
+ liquidity: string;
10
+ raw?: any;
11
+ }
12
+ export declare function applySwapToState(state: LocalClmmState, afterSqrtPrice: string, tick: number, liquidity: string, rawFieldMap: {
13
+ sqrtPrice: string;
14
+ tickIndex: string;
15
+ liquidity: string;
16
+ }): void;
17
+ export declare function applyLiquidityToActiveState(state: LocalClmmState, tickLower: number, tickUpper: number, signedDelta: bigint, rawLiquidityField: string): void;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applySwapToState = applySwapToState;
4
+ exports.applyLiquidityToActiveState = applyLiquidityToActiveState;
5
+ function applySwapToState(state, afterSqrtPrice, tick, liquidity, rawFieldMap) {
6
+ state.currentSqrtPrice = afterSqrtPrice;
7
+ state.currentTickIndex = tick;
8
+ state.liquidity = liquidity;
9
+ if (state.raw) {
10
+ state.raw[rawFieldMap.sqrtPrice] = afterSqrtPrice;
11
+ state.raw[rawFieldMap.tickIndex] = tick;
12
+ state.raw[rawFieldMap.liquidity] = liquidity;
13
+ }
14
+ }
15
+ function applyLiquidityToActiveState(state, tickLower, tickUpper, signedDelta, rawLiquidityField) {
16
+ if (tickLower <= state.currentTickIndex && state.currentTickIndex < tickUpper) {
17
+ const next = BigInt(state.liquidity) + signedDelta;
18
+ state.liquidity = (next < 0n ? 0n : next).toString();
19
+ if (state.raw)
20
+ state.raw[rawLiquidityField] = state.liquidity;
21
+ }
22
+ }
@@ -0,0 +1,42 @@
1
+ export declare const TICK_REFRESH_INTERVAL_MS: number;
2
+ export interface TickInfo {
3
+ liquidityNet: bigint;
4
+ liquidityGross: bigint;
5
+ sqrtPrice?: bigint;
6
+ }
7
+ export interface SuiClmmTickCacheConfig {
8
+ refreshInterval?: number;
9
+ minUpdateInterval?: number;
10
+ }
11
+ export interface SuiTickLoader {
12
+ loadTicks(poolAddress: string): Promise<Map<number, TickInfo>>;
13
+ }
14
+ export declare class SuiClmmTickCache {
15
+ private pools;
16
+ private refreshTimers;
17
+ private loadPromises;
18
+ private loader;
19
+ private config;
20
+ constructor(loader: SuiTickLoader, config?: SuiClmmTickCacheConfig);
21
+ initPool(poolAddress: string, currentTick: number, tickSpacing: number): Promise<void>;
22
+ onSwap(poolAddress: string, newTick: number): void;
23
+ onAdd(poolAddress: string, tickLower: number, tickUpper: number, amount: bigint): void;
24
+ onRemove(poolAddress: string, tickLower: number, tickUpper: number, amount: bigint): void;
25
+ private applyLiquidityDelta;
26
+ private updateTickLiquidity;
27
+ getTickInfo(poolAddress: string, tickIndex: number): TickInfo | undefined;
28
+ getSortedTicks(poolAddress: string): {
29
+ index: number;
30
+ liquidityNet: bigint;
31
+ liquidityGross: bigint;
32
+ sqrtPrice?: bigint;
33
+ }[];
34
+ computeActiveLiquidity(poolAddress: string, currentTick: number): bigint;
35
+ getTickSpacing(poolAddress: string): number | undefined;
36
+ hasPool(poolAddress: string): boolean;
37
+ scheduleFullRefresh(poolAddress: string): Promise<void>;
38
+ private startPeriodicRefresh;
39
+ private doFullRefresh;
40
+ clearPool(poolAddress: string): void;
41
+ destroy(): void;
42
+ }
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SuiClmmTickCache = exports.TICK_REFRESH_INTERVAL_MS = void 0;
4
+ const ttd_core_1 = require("@clonegod/ttd-core");
5
+ exports.TICK_REFRESH_INTERVAL_MS = Number(process.env.TICK_CACHE_FORCE_FULL_REFRESH_INTERVAL) || 60000;
6
+ class SuiClmmTickCache {
7
+ constructor(loader, config = {}) {
8
+ this.pools = new Map();
9
+ this.refreshTimers = new Map();
10
+ this.loadPromises = new Map();
11
+ this.loader = loader;
12
+ this.config = {
13
+ refreshInterval: config.refreshInterval ?? exports.TICK_REFRESH_INTERVAL_MS,
14
+ minUpdateInterval: config.minUpdateInterval ?? (Number(process.env.TICK_CACHE_MIN_UPDATE_INTERVAL) || 3000),
15
+ };
16
+ }
17
+ async initPool(poolAddress, currentTick, tickSpacing) {
18
+ const ticks = await this.loader.loadTicks(poolAddress);
19
+ this.pools.set(poolAddress, {
20
+ ticks,
21
+ currentTick,
22
+ tickSpacing,
23
+ lastFullLoadTime: Date.now(),
24
+ loading: false,
25
+ pendingForceRefresh: false,
26
+ });
27
+ this.startPeriodicRefresh(poolAddress);
28
+ (0, ttd_core_1.log_info)(`[SuiTickCache] Pool ${poolAddress} initialized: ${ticks.size} ticks, tick=${currentTick}, spacing=${tickSpacing}`);
29
+ }
30
+ onSwap(poolAddress, newTick) {
31
+ const state = this.pools.get(poolAddress);
32
+ if (!state)
33
+ return;
34
+ state.currentTick = newTick;
35
+ }
36
+ onAdd(poolAddress, tickLower, tickUpper, amount) {
37
+ this.applyLiquidityDelta(poolAddress, tickLower, tickUpper, amount);
38
+ }
39
+ onRemove(poolAddress, tickLower, tickUpper, amount) {
40
+ this.applyLiquidityDelta(poolAddress, tickLower, tickUpper, -amount);
41
+ }
42
+ applyLiquidityDelta(poolAddress, tickLower, tickUpper, delta) {
43
+ const state = this.pools.get(poolAddress);
44
+ if (!state) {
45
+ (0, ttd_core_1.log_warn)(`[SuiTickCache] Pool ${poolAddress} not initialized, ignoring liquidity event`, '');
46
+ return;
47
+ }
48
+ const absDelta = delta < 0n ? -delta : delta;
49
+ this.updateTickLiquidity(state, tickLower, delta, absDelta);
50
+ this.updateTickLiquidity(state, tickUpper, -delta, absDelta);
51
+ (0, ttd_core_1.log_debug)(`[SuiTickCache] ${poolAddress}: delta applied tickLower=${tickLower} tickUpper=${tickUpper} delta=${delta}`);
52
+ }
53
+ updateTickLiquidity(state, tickIndex, netDelta, grossDelta) {
54
+ const existing = state.ticks.get(tickIndex);
55
+ if (existing) {
56
+ existing.liquidityNet += netDelta;
57
+ existing.liquidityGross += (netDelta > 0n ? grossDelta : -grossDelta);
58
+ if (existing.liquidityGross <= 0n) {
59
+ state.ticks.delete(tickIndex);
60
+ (0, ttd_core_1.log_debug)(`[SuiTickCache] Tick ${tickIndex} de-initialized (gross<=0)`);
61
+ }
62
+ return;
63
+ }
64
+ if (netDelta > 0n || grossDelta > 0n) {
65
+ state.ticks.set(tickIndex, { liquidityNet: netDelta, liquidityGross: grossDelta });
66
+ (0, ttd_core_1.log_debug)(`[SuiTickCache] New tick ${tickIndex} initialized`);
67
+ }
68
+ }
69
+ getTickInfo(poolAddress, tickIndex) {
70
+ return this.pools.get(poolAddress)?.ticks.get(tickIndex);
71
+ }
72
+ getSortedTicks(poolAddress) {
73
+ const state = this.pools.get(poolAddress);
74
+ if (!state)
75
+ return [];
76
+ return Array.from(state.ticks.entries())
77
+ .map(([index, info]) => ({ index, liquidityNet: info.liquidityNet, liquidityGross: info.liquidityGross, sqrtPrice: info.sqrtPrice }))
78
+ .sort((a, b) => a.index - b.index);
79
+ }
80
+ computeActiveLiquidity(poolAddress, currentTick) {
81
+ const state = this.pools.get(poolAddress);
82
+ if (!state)
83
+ return 0n;
84
+ let acc = 0n;
85
+ for (const t of this.getSortedTicks(poolAddress)) {
86
+ if (t.index > currentTick)
87
+ break;
88
+ acc += t.liquidityNet;
89
+ }
90
+ return acc < 0n ? 0n : acc;
91
+ }
92
+ getTickSpacing(poolAddress) {
93
+ return this.pools.get(poolAddress)?.tickSpacing;
94
+ }
95
+ hasPool(poolAddress) {
96
+ return this.pools.has(poolAddress);
97
+ }
98
+ async scheduleFullRefresh(poolAddress) {
99
+ const state = this.pools.get(poolAddress);
100
+ if (!state)
101
+ return;
102
+ const existing = this.loadPromises.get(poolAddress);
103
+ if (existing)
104
+ return existing;
105
+ if (Date.now() - state.lastFullLoadTime < this.config.minUpdateInterval)
106
+ return;
107
+ const promise = this.doFullRefresh(poolAddress).finally(() => this.loadPromises.delete(poolAddress));
108
+ this.loadPromises.set(poolAddress, promise);
109
+ return promise;
110
+ }
111
+ startPeriodicRefresh(poolAddress) {
112
+ const old = this.refreshTimers.get(poolAddress);
113
+ if (old)
114
+ clearInterval(old);
115
+ const timer = setInterval(async () => {
116
+ try {
117
+ await this.doFullRefresh(poolAddress);
118
+ }
119
+ catch (err) {
120
+ (0, ttd_core_1.log_warn)(`[SuiTickCache] periodic refresh failed ${poolAddress}: ${err.message}`, '');
121
+ }
122
+ }, this.config.refreshInterval);
123
+ this.refreshTimers.set(poolAddress, timer);
124
+ }
125
+ async doFullRefresh(poolAddress) {
126
+ const state = this.pools.get(poolAddress);
127
+ if (!state)
128
+ return;
129
+ if (state.loading) {
130
+ state.pendingForceRefresh = true;
131
+ return;
132
+ }
133
+ state.loading = true;
134
+ try {
135
+ const ticks = await this.loader.loadTicks(poolAddress);
136
+ state.ticks = ticks;
137
+ state.lastFullLoadTime = Date.now();
138
+ state.pendingForceRefresh = false;
139
+ (0, ttd_core_1.log_debug)(`[SuiTickCache] full refresh ${poolAddress}: ${ticks.size} ticks`);
140
+ }
141
+ finally {
142
+ state.loading = false;
143
+ if (state.pendingForceRefresh) {
144
+ state.pendingForceRefresh = false;
145
+ this.doFullRefresh(poolAddress).catch(() => { });
146
+ }
147
+ }
148
+ }
149
+ clearPool(poolAddress) {
150
+ this.pools.delete(poolAddress);
151
+ const timer = this.refreshTimers.get(poolAddress);
152
+ if (timer) {
153
+ clearInterval(timer);
154
+ this.refreshTimers.delete(poolAddress);
155
+ }
156
+ this.loadPromises.delete(poolAddress);
157
+ }
158
+ destroy() {
159
+ for (const [addr] of this.pools)
160
+ this.clearPool(addr);
161
+ }
162
+ }
163
+ exports.SuiClmmTickCache = SuiClmmTickCache;
@@ -0,0 +1,2 @@
1
+ import { SuiClmmTickCache } from './sui_clmm_tick_cache';
2
+ export declare function buildSwapTicks<T>(cache: SuiClmmTickCache, poolAddress: string, mkTick: (index: number, liquidityNet: bigint, liquidityGross: bigint, sqrtPrice?: bigint) => T): T[];
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildSwapTicks = buildSwapTicks;
4
+ function buildSwapTicks(cache, poolAddress, mkTick) {
5
+ return cache.getSortedTicks(poolAddress).map(t => mkTick(t.index, t.liquidityNet, t.liquidityGross, t.sqrtPrice));
6
+ }
@@ -0,0 +1 @@
1
+ export * from './quote_price_verify';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./quote_price_verify"), exports);
@@ -0,0 +1,30 @@
1
+ import { QuoteTier } from '@clonegod/ttd-core';
2
+ export interface CheckSwapParams {
3
+ poolAddress: string;
4
+ poolName: string;
5
+ blockNumber: number;
6
+ txHash: string;
7
+ amount0: string;
8
+ amount1: string;
9
+ token0Address: string;
10
+ token1Address: string;
11
+ token0Decimals: number;
12
+ token1Decimals: number;
13
+ poolInfo: {
14
+ tokenA: any;
15
+ tokenB: any;
16
+ quote_token: string;
17
+ };
18
+ swapperDeltaConvention?: boolean;
19
+ }
20
+ export declare class QuotePriceVerify {
21
+ private quoteCache;
22
+ private get enabled();
23
+ cacheQuote(poolAddress: string, priceId: string, source: string, askPrice: number, bidPrice: number, blockNumber: number, quoteAmountUsd: number, token0PriceUsd?: number, token1PriceUsd?: number, tiers?: {
24
+ askTiers?: QuoteTier[];
25
+ bidTiers?: QuoteTier[];
26
+ }): void;
27
+ checkSwap(params: CheckSwapParams): string | void;
28
+ private deriveSwapDirection;
29
+ private compareAndLog;
30
+ }