@clonegod/ttd-sol-common 2.0.67 → 2.0.69

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 (94) hide show
  1. package/dist/appconfig/SolanaQuoteAppConfig.d.ts +9 -0
  2. package/dist/appconfig/SolanaQuoteAppConfig.js +29 -0
  3. package/dist/appconfig/SolanaTradeAppConfig.d.ts +13 -0
  4. package/dist/{config → appconfig}/SolanaTradeAppConfig.js +25 -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/sol_dex_env_args.d.ts +5 -0
  10. package/dist/appconfig/sol_dex_env_args.js +29 -0
  11. package/dist/appconfig/sol_env_args.d.ts +17 -0
  12. package/dist/appconfig/sol_env_args.js +37 -0
  13. package/dist/common/get_wallet_token_account.js +13 -16
  14. package/dist/grpc/grpc_provider_registry.d.ts +14 -0
  15. package/dist/grpc/grpc_provider_registry.js +70 -0
  16. package/dist/grpc/index.d.ts +1 -0
  17. package/dist/grpc/index.js +17 -0
  18. package/dist/index.d.ts +3 -0
  19. package/dist/index.js +3 -0
  20. package/dist/quote/abstract_dex_quote.d.ts +68 -0
  21. package/dist/quote/abstract_dex_quote.js +208 -0
  22. package/dist/quote/chain_ops.d.ts +18 -0
  23. package/dist/quote/chain_ops.js +66 -0
  24. package/dist/quote/depth/amm_depth_calculator.d.ts +19 -0
  25. package/dist/quote/depth/amm_depth_calculator.js +55 -0
  26. package/dist/quote/depth/clmm_depth_calculator.d.ts +42 -0
  27. package/dist/quote/depth/clmm_depth_calculator.js +173 -0
  28. package/dist/quote/depth/index.d.ts +37 -0
  29. package/dist/quote/depth/index.js +164 -0
  30. package/dist/quote/index.d.ts +9 -0
  31. package/dist/quote/index.js +9 -0
  32. package/dist/quote/pool_event.d.ts +20 -0
  33. package/dist/quote/pool_event.js +22 -0
  34. package/dist/quote/pool_subscription_registry.d.ts +4 -0
  35. package/dist/quote/pool_subscription_registry.js +62 -0
  36. package/dist/quote/quote_amount.d.ts +4 -0
  37. package/dist/quote/quote_amount.js +24 -0
  38. package/dist/quote/quote_trace.d.ts +16 -0
  39. package/dist/quote/quote_trace.js +40 -0
  40. package/dist/quote/tick/clmm_tick_math.d.ts +5 -0
  41. package/dist/quote/tick/clmm_tick_math.js +61 -0
  42. package/dist/quote/tick/index.d.ts +1 -0
  43. package/dist/{config → quote/tick}/index.js +1 -1
  44. package/dist/quote/verify/index.d.ts +1 -0
  45. package/dist/quote/verify/index.js +17 -0
  46. package/dist/quote/verify/quote_price_verify.d.ts +30 -0
  47. package/dist/quote/verify/quote_price_verify.js +247 -0
  48. package/dist/trade/index.d.ts +0 -1
  49. package/dist/trade/index.js +0 -1
  50. package/dist/trade/tx_builder.d.ts +1 -1
  51. package/dist/trade/tx_result_parse.js +1 -0
  52. package/dist/types/index.d.ts +9 -1
  53. package/dist/types/index.js +2 -0
  54. package/dist/utils/index.d.ts +1 -0
  55. package/dist/utils/index.js +17 -0
  56. package/dist/utils/trade_direction.d.ts +14 -0
  57. package/dist/utils/trade_direction.js +23 -0
  58. package/package.json +4 -4
  59. package/src/appconfig/SolanaQuoteAppConfig.ts +55 -0
  60. package/src/appconfig/SolanaTradeAppConfig.ts +117 -0
  61. package/src/appconfig/ensure_core_env.ts +28 -0
  62. package/src/appconfig/index.ts +5 -0
  63. package/src/appconfig/sol_dex_env_args.ts +52 -0
  64. package/src/appconfig/sol_env_args.ts +79 -0
  65. package/src/common/get_wallet_token_account.ts +27 -33
  66. package/src/grpc/grpc_provider_registry.ts +103 -0
  67. package/src/grpc/index.ts +1 -0
  68. package/src/index.ts +3 -0
  69. package/src/quote/abstract_dex_quote.ts +337 -0
  70. package/src/quote/chain_ops.ts +91 -0
  71. package/src/quote/depth/amm_depth_calculator.ts +143 -0
  72. package/src/quote/depth/clmm_depth_calculator.ts +321 -0
  73. package/src/quote/depth/index.ts +272 -0
  74. package/src/quote/index.ts +9 -0
  75. package/src/quote/pool_event.ts +82 -0
  76. package/src/quote/pool_subscription_registry.ts +81 -0
  77. package/src/quote/quote_amount.ts +37 -0
  78. package/src/quote/quote_trace.ts +56 -0
  79. package/src/quote/tick/clmm_tick_math.ts +77 -0
  80. package/src/quote/tick/index.ts +1 -0
  81. package/src/quote/verify/index.ts +1 -0
  82. package/src/quote/verify/quote_price_verify.ts +508 -0
  83. package/src/trade/index.ts +0 -1
  84. package/src/trade/tx_builder.ts +1 -1
  85. package/src/trade/tx_result_parse.ts +1 -0
  86. package/src/types/index.ts +20 -2
  87. package/src/utils/index.ts +1 -0
  88. package/src/utils/trade_direction.ts +68 -0
  89. package/dist/config/SolanaTradeAppConfig.d.ts +0 -10
  90. package/dist/config/index.d.ts +0 -1
  91. package/dist/trade/SolanaTradeAppConfig.d.ts +0 -8
  92. package/dist/trade/SolanaTradeAppConfig.js +0 -26
  93. package/src/config/SolanaTradeAppConfig.ts +0 -70
  94. package/src/config/index.ts +0 -2
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateAmmDepth = exports.swapExactInClmm = exports.bigIntSqrt = exports.computeTargetSqrtX64 = exports.priceFromSqrtX64 = exports.calculateClmmDepth = void 0;
4
+ exports.grossUpFee = grossUpFee;
5
+ exports.assembleEntry = assembleEntry;
6
+ exports.buildClmmDepth = buildClmmDepth;
7
+ exports.buildAmmDepth = buildAmmDepth;
8
+ const dist_1 = require("@clonegod/ttd-core/dist");
9
+ const dist_2 = require("@clonegod/ttd-core/dist");
10
+ const trade_direction_1 = require("../../utils/trade_direction");
11
+ const clmm_depth_calculator_1 = require("./clmm_depth_calculator");
12
+ const amm_depth_calculator_1 = require("./amm_depth_calculator");
13
+ var clmm_depth_calculator_2 = require("./clmm_depth_calculator");
14
+ Object.defineProperty(exports, "calculateClmmDepth", { enumerable: true, get: function () { return clmm_depth_calculator_2.calculateClmmDepth; } });
15
+ Object.defineProperty(exports, "priceFromSqrtX64", { enumerable: true, get: function () { return clmm_depth_calculator_2.priceFromSqrtX64; } });
16
+ Object.defineProperty(exports, "computeTargetSqrtX64", { enumerable: true, get: function () { return clmm_depth_calculator_2.computeTargetSqrtX64; } });
17
+ Object.defineProperty(exports, "bigIntSqrt", { enumerable: true, get: function () { return clmm_depth_calculator_2.bigIntSqrt; } });
18
+ Object.defineProperty(exports, "swapExactInClmm", { enumerable: true, get: function () { return clmm_depth_calculator_2.swapExactInClmm; } });
19
+ var amm_depth_calculator_2 = require("./amm_depth_calculator");
20
+ Object.defineProperty(exports, "calculateAmmDepth", { enumerable: true, get: function () { return amm_depth_calculator_2.calculateAmmDepth; } });
21
+ let _depthPctLogged = false;
22
+ function logDepthLevelsOnce() {
23
+ if (_depthPctLogged)
24
+ return;
25
+ _depthPctLogged = true;
26
+ (0, dist_1.log_info)(`[Depth] pctLevels=${JSON.stringify((0, dist_2.getDepthPricePctLevels)())}, default=${dist_2.DEFAULT_TIER_PCT}`);
27
+ }
28
+ function grossUpFee(amountInNet, feeRateBps) {
29
+ if (feeRateBps <= 0 || amountInNet <= 0)
30
+ return { amountInGross: amountInNet, feeAmount: 0 };
31
+ const feeRatio = feeRateBps / 10000;
32
+ const amountInGross = amountInNet / (1 - feeRatio);
33
+ return { amountInGross, feeAmount: amountInGross - amountInNet };
34
+ }
35
+ function assembleEntry(tiers) {
36
+ const def = tiers.find(t => t.pct === dist_2.DEFAULT_TIER_PCT) ?? tiers[0];
37
+ return {
38
+ price: def.price, amount: def.amount, amount_in: def.amount_in, amount_in_usd: def.amount_in_usd,
39
+ fee: def.fee, fee_usd: def.fee_usd, tick_move: def.tick_move, tiers,
40
+ };
41
+ }
42
+ function buildClmmDepth(input) {
43
+ logDepthLevelsOnce();
44
+ const pctLevels = (0, dist_2.getDepthPricePctLevels)();
45
+ if (pctLevels.length === 0)
46
+ return undefined;
47
+ const { poolInfo, poolState, ticks, basePriceUsd, quotePriceUsd, feeRateBps } = input;
48
+ if (poolState.liquidity <= 0n)
49
+ return undefined;
50
+ if (feeRateBps == null || feeRateBps < 0) {
51
+ (0, dist_1.log_debug)(`[Depth] ${poolInfo.pool_name} CLMM: invalid feeRateBps=${feeRateBps}, skip`, '');
52
+ return undefined;
53
+ }
54
+ try {
55
+ const dir = (0, trade_direction_1.resolveTradeDirection)(poolInfo, true);
56
+ const baseToken = dir.baseToken;
57
+ const quoteToken = dir.quoteToken;
58
+ const baseIsToken0 = poolState.baseIsToken0;
59
+ const askZeroForOne = !baseIsToken0;
60
+ const bidZeroForOne = baseIsToken0;
61
+ const midPrice = (0, clmm_depth_calculator_1.priceFromSqrtX64)(poolState.currentSqrtPriceX64, baseToken.decimals, quoteToken.decimals, baseIsToken0);
62
+ const askTiers = [];
63
+ const bidTiers = [];
64
+ for (const pct of pctLevels) {
65
+ const bps = Math.round(pct * 100);
66
+ const askResult = (0, clmm_depth_calculator_1.calculateClmmDepth)({
67
+ sqrtPriceX64: poolState.currentSqrtPriceX64, currentTick: poolState.currentTick,
68
+ liquidity: poolState.liquidity, ticks, zeroForOne: askZeroForOne, targetBps: bps,
69
+ inputDecimals: quoteToken.decimals, outputDecimals: baseToken.decimals,
70
+ });
71
+ const bidResult = (0, clmm_depth_calculator_1.calculateClmmDepth)({
72
+ sqrtPriceX64: poolState.currentSqrtPriceX64, currentTick: poolState.currentTick,
73
+ liquidity: poolState.liquidity, ticks, zeroForOne: bidZeroForOne, targetBps: bps,
74
+ inputDecimals: baseToken.decimals, outputDecimals: quoteToken.decimals,
75
+ });
76
+ const askTargetPrice = (0, clmm_depth_calculator_1.priceFromSqrtX64)(askResult.targetSqrtPriceX64, baseToken.decimals, quoteToken.decimals, baseIsToken0);
77
+ const bidTargetPrice = (0, clmm_depth_calculator_1.priceFromSqrtX64)(bidResult.targetSqrtPriceX64, baseToken.decimals, quoteToken.decimals, baseIsToken0);
78
+ const askGross = grossUpFee(askResult.amountIn, feeRateBps);
79
+ const bidGross = grossUpFee(bidResult.amountIn, feeRateBps);
80
+ const askTickMove = `${askResult.targetTick} <- ${askResult.currentTick}`;
81
+ const bidTickMove = `${bidResult.currentTick} -> ${bidResult.targetTick}`;
82
+ const askEffPrice = askResult.amountOut > 0 ? askGross.amountInGross / askResult.amountOut : askTargetPrice;
83
+ const bidEffPrice = bidGross.amountInGross > 0 ? bidResult.amountOut / bidGross.amountInGross : bidTargetPrice;
84
+ askTiers.push({
85
+ pct, price: askEffPrice, amount: askResult.amountOut,
86
+ amount_in: askGross.amountInGross, amount_in_usd: askGross.amountInGross * quotePriceUsd,
87
+ fee: askGross.feeAmount, fee_usd: askGross.feeAmount * quotePriceUsd, tick_move: askTickMove,
88
+ });
89
+ bidTiers.push({
90
+ pct, price: bidEffPrice, amount: bidResult.amountOut,
91
+ amount_in: bidGross.amountInGross, amount_in_usd: bidGross.amountInGross * basePriceUsd,
92
+ fee: bidGross.feeAmount, fee_usd: bidGross.feeAmount * basePriceUsd, tick_move: bidTickMove,
93
+ });
94
+ }
95
+ return {
96
+ mid_price: midPrice,
97
+ fee_rate_bps: feeRateBps,
98
+ ask: assembleEntry(askTiers),
99
+ bid: assembleEntry(bidTiers),
100
+ };
101
+ }
102
+ catch (error) {
103
+ (0, dist_1.log_debug)(`[Depth] ${poolInfo.pool_name} CLMM depth failed: ${error.message}`, '');
104
+ return undefined;
105
+ }
106
+ }
107
+ function buildAmmDepth(input) {
108
+ logDepthLevelsOnce();
109
+ const pctLevels = (0, dist_2.getDepthPricePctLevels)();
110
+ if (pctLevels.length === 0)
111
+ return undefined;
112
+ const { poolInfo, reserve0, reserve1, baseIsToken0, basePriceUsd, quotePriceUsd, feeRateBps } = input;
113
+ if (feeRateBps == null || feeRateBps < 0) {
114
+ (0, dist_1.log_debug)(`[Depth] ${poolInfo.pool_name} AMM: invalid feeRateBps=${feeRateBps}, skip`, '');
115
+ return undefined;
116
+ }
117
+ try {
118
+ const dir = (0, trade_direction_1.resolveTradeDirection)(poolInfo, true);
119
+ const baseToken = dir.baseToken;
120
+ const quoteToken = dir.quoteToken;
121
+ const baseReserveUi = Number(BigInt(baseIsToken0 ? reserve0 : reserve1)) / Math.pow(10, baseToken.decimals);
122
+ const quoteReserveUi = Number(BigInt(baseIsToken0 ? reserve1 : reserve0)) / Math.pow(10, quoteToken.decimals);
123
+ const midPrice = quoteReserveUi / baseReserveUi;
124
+ const askTiers = [];
125
+ const bidTiers = [];
126
+ for (const pct of pctLevels) {
127
+ const bps = Math.round(pct * 100);
128
+ const askResult = (0, amm_depth_calculator_1.calculateAmmDepth)({
129
+ reserve0, reserve1, targetBps: bps, isBuy: true, baseIsToken0,
130
+ token0Decimals: baseIsToken0 ? baseToken.decimals : quoteToken.decimals,
131
+ token1Decimals: baseIsToken0 ? quoteToken.decimals : baseToken.decimals,
132
+ });
133
+ const bidResult = (0, amm_depth_calculator_1.calculateAmmDepth)({
134
+ reserve0, reserve1, targetBps: bps, isBuy: false, baseIsToken0,
135
+ token0Decimals: baseIsToken0 ? baseToken.decimals : quoteToken.decimals,
136
+ token1Decimals: baseIsToken0 ? quoteToken.decimals : baseToken.decimals,
137
+ });
138
+ const askGross = grossUpFee(askResult.amountIn, feeRateBps);
139
+ const bidGross = grossUpFee(bidResult.amountIn, feeRateBps);
140
+ const askEffPrice = askResult.amountOut > 0 ? askGross.amountInGross / askResult.amountOut : askResult.targetPrice;
141
+ const bidEffPrice = bidGross.amountInGross > 0 ? bidResult.amountOut / bidGross.amountInGross : bidResult.targetPrice;
142
+ askTiers.push({
143
+ pct, price: askEffPrice, amount: askResult.amountOut,
144
+ amount_in: askGross.amountInGross, amount_in_usd: askGross.amountInGross * quotePriceUsd,
145
+ fee: askGross.feeAmount, fee_usd: askGross.feeAmount * quotePriceUsd,
146
+ });
147
+ bidTiers.push({
148
+ pct, price: bidEffPrice, amount: bidResult.amountOut,
149
+ amount_in: bidGross.amountInGross, amount_in_usd: bidGross.amountInGross * basePriceUsd,
150
+ fee: bidGross.feeAmount, fee_usd: bidGross.feeAmount * basePriceUsd,
151
+ });
152
+ }
153
+ return {
154
+ mid_price: midPrice,
155
+ fee_rate_bps: feeRateBps,
156
+ ask: assembleEntry(askTiers),
157
+ bid: assembleEntry(bidTiers),
158
+ };
159
+ }
160
+ catch (error) {
161
+ (0, dist_1.log_debug)(`[Depth] ${poolInfo.pool_name} AMM depth failed: ${error.message}`, '');
162
+ return undefined;
163
+ }
164
+ }
@@ -1 +1,10 @@
1
1
  export * from './pricing';
2
+ export * from './pool_subscription_registry';
3
+ export * from './pool_event';
4
+ export * from './chain_ops';
5
+ export * from './abstract_dex_quote';
6
+ export * from './quote_trace';
7
+ export * from './quote_amount';
8
+ export * from './verify';
9
+ export * from './depth';
10
+ export * from './tick';
@@ -15,3 +15,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./pricing"), exports);
18
+ __exportStar(require("./pool_subscription_registry"), exports);
19
+ __exportStar(require("./pool_event"), exports);
20
+ __exportStar(require("./chain_ops"), exports);
21
+ __exportStar(require("./abstract_dex_quote"), exports);
22
+ __exportStar(require("./quote_trace"), exports);
23
+ __exportStar(require("./quote_amount"), exports);
24
+ __exportStar(require("./verify"), exports);
25
+ __exportStar(require("./depth"), exports);
26
+ __exportStar(require("./tick"), exports);
@@ -0,0 +1,20 @@
1
+ import { SolanaPoolAccountUpdateEventData } from '../types';
2
+ export interface SolPoolEvent {
3
+ pool_address: string;
4
+ dex_id: string;
5
+ pool_name: string;
6
+ blockNumber: number;
7
+ writeVersion?: number;
8
+ txHash: string;
9
+ blockTime: number;
10
+ poolAccountData: string;
11
+ vaultAAccountData?: string;
12
+ vaultBAccountData?: string;
13
+ subAccount?: {
14
+ role: string;
15
+ address: string;
16
+ data: string;
17
+ };
18
+ raw: SolanaPoolAccountUpdateEventData;
19
+ }
20
+ export declare function toSolPoolEvent(data: SolanaPoolAccountUpdateEventData): SolPoolEvent;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toSolPoolEvent = toSolPoolEvent;
4
+ function toSolPoolEvent(data) {
5
+ const d = data.data;
6
+ return {
7
+ pool_address: data.pool_address,
8
+ dex_id: data.dex_id,
9
+ pool_name: data.pool_name,
10
+ blockNumber: d.slot,
11
+ writeVersion: d.write_version,
12
+ txHash: d.tx_hash || 'account',
13
+ blockTime: data.event_time || 0,
14
+ poolAccountData: d.pool_account_data,
15
+ vaultAAccountData: d.vaultA_account_data,
16
+ vaultBAccountData: d.vaultB_account_data,
17
+ subAccount: d.sub_account
18
+ ? { role: d.sub_account.role, address: d.sub_account.account, data: d.sub_account.account_data }
19
+ : undefined,
20
+ raw: data,
21
+ };
22
+ }
@@ -0,0 +1,4 @@
1
+ import { AppConfig, StandardPoolInfoType } from '@clonegod/ttd-core/dist';
2
+ export declare function registerPoolSubscriptions(appConfig: AppConfig, pools: StandardPoolInfoType[], quote_app_id: string): Promise<void>;
3
+ export declare function unregisterPoolSubscriptions(appConfig: AppConfig, quote_app_id: string): Promise<void>;
4
+ export declare function attachPoolSubscriptionLifecycle(appConfig: AppConfig, pools: StandardPoolInfoType[]): Promise<void>;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerPoolSubscriptions = registerPoolSubscriptions;
4
+ exports.unregisterPoolSubscriptions = unregisterPoolSubscriptions;
5
+ exports.attachPoolSubscriptionLifecycle = attachPoolSubscriptionLifecycle;
6
+ const dist_1 = require("@clonegod/ttd-core/dist");
7
+ const grpc_provider_registry_1 = require("../grpc/grpc_provider_registry");
8
+ function configCenterBase(appConfig) {
9
+ const chain = appConfig.env_args.chain_id;
10
+ let host = String(appConfig.env_args.config_center_host || '127.0.0.1').trim();
11
+ if (!host.includes(':'))
12
+ host = `${host}:${dist_1.SERVICE_PORT.CONFIG_CENTER_HTTP}`;
13
+ return `http://${host}/${chain}/config`;
14
+ }
15
+ async function registerPoolSubscriptions(appConfig, pools, quote_app_id) {
16
+ const provider = await (0, grpc_provider_registry_1.resolveGrpcProvider)(appConfig.arb_cache.redis_cmd, appConfig.env_args.chain_id);
17
+ const provider_ids = [provider.id];
18
+ const base = configCenterBase(appConfig);
19
+ let ok = 0;
20
+ for (const p of pools) {
21
+ try {
22
+ await dist_1.HttpUtil.post(`${base}/quote/register`, {
23
+ pool_address: p.pool_address,
24
+ provider_ids,
25
+ quote_app_id,
26
+ pair: p.pair,
27
+ dex_id: p.dex_id,
28
+ pool_name: p.pool_name,
29
+ fee_rate: p.fee_rate,
30
+ });
31
+ ok++;
32
+ }
33
+ catch (e) {
34
+ (0, dist_1.log_warn)(`[pool/subscriptions] register ${p.pool_address} failed: ${e.message}`);
35
+ }
36
+ }
37
+ (0, dist_1.log_info)(`[pool/subscriptions] registered ${ok}/${pools.length} pools by ${quote_app_id} → provider=${provider.id}`);
38
+ }
39
+ async function unregisterPoolSubscriptions(appConfig, quote_app_id) {
40
+ try {
41
+ await dist_1.HttpUtil.post(`${configCenterBase(appConfig)}/quote/unregister`, { quote_app_id });
42
+ (0, dist_1.log_info)(`[pool/subscriptions] unregistered all pools by ${quote_app_id}`);
43
+ }
44
+ catch (e) {
45
+ (0, dist_1.log_warn)(`[pool/subscriptions] unregister failed: ${e.message}`);
46
+ }
47
+ }
48
+ async function attachPoolSubscriptionLifecycle(appConfig, pools) {
49
+ const quote_app_id = String(appConfig.env_args.app_name || '').toLowerCase() || 'sol-quote';
50
+ await registerPoolSubscriptions(appConfig, pools, quote_app_id);
51
+ let cleaned = false;
52
+ const cleanup = async (sig) => {
53
+ if (cleaned)
54
+ return;
55
+ cleaned = true;
56
+ (0, dist_1.log_info)(`[pool/subscriptions] ${sig} → unregister ${quote_app_id}`);
57
+ await unregisterPoolSubscriptions(appConfig, quote_app_id);
58
+ process.exit(0);
59
+ };
60
+ process.on('SIGINT', () => void cleanup('SIGINT'));
61
+ process.on('SIGTERM', () => void cleanup('SIGTERM'));
62
+ }
@@ -0,0 +1,4 @@
1
+ import { StandardPoolInfoType } from '@clonegod/ttd-core';
2
+ import Decimal from 'decimal.js';
3
+ export declare function getQuoteAmountUsd(poolInfo: StandardPoolInfoType): number;
4
+ export declare function usdToTokenUiAmount(amountInUsd: number, tokenAddress: string): Promise<Decimal>;
@@ -0,0 +1,24 @@
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.getQuoteAmountUsd = getQuoteAmountUsd;
7
+ exports.usdToTokenUiAmount = usdToTokenUiAmount;
8
+ const ttd_core_1 = require("@clonegod/ttd-core");
9
+ const decimal_js_1 = __importDefault(require("decimal.js"));
10
+ function getQuoteAmountUsd(poolInfo) {
11
+ const envValue = Number(process.env.QUOTE_AMOUNT_USD);
12
+ if (envValue > 0) {
13
+ return envValue;
14
+ }
15
+ return poolInfo.quote_amount_usd;
16
+ }
17
+ async function usdToTokenUiAmount(amountInUsd, tokenAddress) {
18
+ const priceMap = await (0, ttd_core_1.get_solana_token_price_info)([tokenAddress]);
19
+ const price = priceMap.get(tokenAddress)?.price;
20
+ if (!price || price === '0') {
21
+ throw new Error(`price not available for ${tokenAddress}`);
22
+ }
23
+ return new decimal_js_1.default(amountInUsd).div(new decimal_js_1.default(price));
24
+ }
@@ -0,0 +1,16 @@
1
+ export declare class QuoteTrace {
2
+ readonly poolName: string;
3
+ readonly poolAddress: string;
4
+ blockNumber: number;
5
+ source: string;
6
+ private startTime;
7
+ private marks;
8
+ private data;
9
+ private error;
10
+ constructor(poolName: string, poolAddress: string, blockNumber?: number, source?: string);
11
+ mark(name: string): void;
12
+ set(key: string, value: any): void;
13
+ markError(stage: string, message: string): void;
14
+ private buildTimeline;
15
+ flush(): void;
16
+ }
@@ -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,5 @@
1
+ export declare const MIN_TICK = -443636;
2
+ export declare const MAX_TICK = 443636;
3
+ export declare const MIN_SQRT_PRICE_X64 = 4295048016n;
4
+ export declare const MAX_SQRT_PRICE_X64 = 79226673521066979257578248091n;
5
+ export declare function getSqrtPriceX64FromTick(tick: number): bigint;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAX_SQRT_PRICE_X64 = exports.MIN_SQRT_PRICE_X64 = exports.MAX_TICK = exports.MIN_TICK = void 0;
4
+ exports.getSqrtPriceX64FromTick = getSqrtPriceX64FromTick;
5
+ exports.MIN_TICK = -443636;
6
+ exports.MAX_TICK = 443636;
7
+ exports.MIN_SQRT_PRICE_X64 = 4295048016n;
8
+ exports.MAX_SQRT_PRICE_X64 = 79226673521066979257578248091n;
9
+ const MaxUint128 = (1n << 128n) - 1n;
10
+ function mulRightShift(val, mulBy) {
11
+ return (val * mulBy) >> 64n;
12
+ }
13
+ function getSqrtPriceX64FromTick(tick) {
14
+ if (!Number.isInteger(tick)) {
15
+ throw new Error('tick must be integer');
16
+ }
17
+ if (tick < exports.MIN_TICK || tick > exports.MAX_TICK) {
18
+ throw new Error('tick must be in MIN_TICK and MAX_TICK');
19
+ }
20
+ const tickAbs = tick < 0 ? -tick : tick;
21
+ let ratio = (tickAbs & 0x1) !== 0 ? 18445821805675395072n : 18446744073709551616n;
22
+ if ((tickAbs & 0x2) !== 0)
23
+ ratio = mulRightShift(ratio, 18444899583751176192n);
24
+ if ((tickAbs & 0x4) !== 0)
25
+ ratio = mulRightShift(ratio, 18443055278223355904n);
26
+ if ((tickAbs & 0x8) !== 0)
27
+ ratio = mulRightShift(ratio, 18439367220385607680n);
28
+ if ((tickAbs & 0x10) !== 0)
29
+ ratio = mulRightShift(ratio, 18431993317065453568n);
30
+ if ((tickAbs & 0x20) !== 0)
31
+ ratio = mulRightShift(ratio, 18417254355718170624n);
32
+ if ((tickAbs & 0x40) !== 0)
33
+ ratio = mulRightShift(ratio, 18387811781193609216n);
34
+ if ((tickAbs & 0x80) !== 0)
35
+ ratio = mulRightShift(ratio, 18329067761203558400n);
36
+ if ((tickAbs & 0x100) !== 0)
37
+ ratio = mulRightShift(ratio, 18212142134806163456n);
38
+ if ((tickAbs & 0x200) !== 0)
39
+ ratio = mulRightShift(ratio, 17980523815641700352n);
40
+ if ((tickAbs & 0x400) !== 0)
41
+ ratio = mulRightShift(ratio, 17526086738831433728n);
42
+ if ((tickAbs & 0x800) !== 0)
43
+ ratio = mulRightShift(ratio, 16651378430235570176n);
44
+ if ((tickAbs & 0x1000) !== 0)
45
+ ratio = mulRightShift(ratio, 15030750278694412288n);
46
+ if ((tickAbs & 0x2000) !== 0)
47
+ ratio = mulRightShift(ratio, 12247334978884435968n);
48
+ if ((tickAbs & 0x4000) !== 0)
49
+ ratio = mulRightShift(ratio, 8131365268886854656n);
50
+ if ((tickAbs & 0x8000) !== 0)
51
+ ratio = mulRightShift(ratio, 3584323654725218816n);
52
+ if ((tickAbs & 0x10000) !== 0)
53
+ ratio = mulRightShift(ratio, 696457651848324352n);
54
+ if ((tickAbs & 0x20000) !== 0)
55
+ ratio = mulRightShift(ratio, 26294789957507116n);
56
+ if ((tickAbs & 0x40000) !== 0)
57
+ ratio = mulRightShift(ratio, 37481735321082n);
58
+ if (tick > 0)
59
+ ratio = MaxUint128 / ratio;
60
+ return ratio;
61
+ }
@@ -0,0 +1 @@
1
+ export * from './clmm_tick_math';
@@ -14,4 +14,4 @@ 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("./SolanaTradeAppConfig"), exports);
17
+ __exportStar(require("./clmm_tick_math"), exports);
@@ -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
+ }