@clonegod/ttd-sol-common 2.0.82 → 2.0.84

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.
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.QuotePriceVerify = void 0;
4
4
  const trade_direction_1 = require("../../utils/trade_direction");
5
5
  const ttd_core_1 = require("@clonegod/ttd-core");
6
+ const USD_STABLECOINS = new Set(['USDT', 'USDC', 'USD1']);
6
7
  function pickMatchingTier(tiers, actualAmountIn) {
7
8
  if (!tiers || tiers.length === 0)
8
9
  return null;
@@ -183,25 +184,24 @@ class QuotePriceVerify {
183
184
  compareAndLog(poolAddress, poolName, poolInfo, cached, inputTokenAddress, outputTokenAddress, inputAmountUi, outputAmountUi, refPrice, execPriceNum, token0PriceUsd, token1PriceUsd, token0Address, swapBlockNumber, txHash, sources, primaryTierInfo) {
184
185
  if (inputAmountUi <= 0 || outputAmountUi <= 0)
185
186
  return;
186
- let swapUsd = 0;
187
- if (token0PriceUsd && token1PriceUsd && token0Address) {
188
- const inputIsToken0 = inputTokenAddress.toLowerCase() === token0Address.toLowerCase();
189
- swapUsd = inputIsToken0
190
- ? inputAmountUi * token0PriceUsd
191
- : inputAmountUi * token1PriceUsd;
192
- }
193
187
  const direction = (0, trade_direction_1.resolveTradeDirection)(poolInfo, true);
194
188
  const baseToken = direction.baseToken;
195
189
  const quoteToken = direction.quoteToken;
196
190
  const inputIsQuoteToken = inputTokenAddress.toLowerCase() === quoteToken.address.toLowerCase();
197
191
  const isBuy = inputIsQuoteToken;
198
192
  const side = isBuy ? 'BUY' : 'SELL';
193
+ const quoteIsToken0 = quoteToken.address === token0Address;
194
+ const quotePriceUsd = USD_STABLECOINS.has((quoteToken.symbol || '').toUpperCase())
195
+ ? 1
196
+ : (quoteIsToken0 ? (token0PriceUsd || 0) : (token1PriceUsd || 0));
197
+ const quoteLegAmount = isBuy ? inputAmountUi : outputAmountUi;
198
+ const swapUsd = quotePriceUsd > 0 ? quoteLegAmount * quotePriceUsd : 0;
199
199
  if (refPrice <= 0 || execPriceNum <= 0)
200
200
  return;
201
201
  const diffBps = (refPrice - execPriceNum) / refPrice * 10000;
202
202
  const absDiffBps = Math.abs(diffBps);
203
203
  const status = absDiffBps < 5 ? '✅' : absDiffBps < 10 ? '⚠️' : '❌';
204
- const usdStr = swapUsd > 0 ? `$${swapUsd.toFixed(0)}` : '$?';
204
+ const usdStr = swapUsd > 0 ? `$${swapUsd.toFixed(2)}` : '$?';
205
205
  const maxUsd = cached.quoteAmountUsd * 2;
206
206
  const inRange = swapUsd <= 0 || swapUsd <= maxUsd;
207
207
  const rangeTag = inRange ? '' : ' [out]';
@@ -229,7 +229,7 @@ class QuotePriceVerify {
229
229
  ref_price: refPrice,
230
230
  exec_price: execPriceNum,
231
231
  diff_bps: parseFloat(diffBps.toFixed(1)),
232
- swap_usd: parseFloat(swapUsd.toFixed(0)),
232
+ swap_usd: parseFloat(swapUsd.toFixed(2)),
233
233
  in_range: inRange,
234
234
  input_amount: inputAmountUi,
235
235
  output_amount: outputAmountUi,
@@ -41,9 +41,11 @@ const jitodontfrontAccounts = [
41
41
  'jitodontfront1111111111111111111111111111wP',
42
42
  'jitodontfront111111111111234565432123456RX5',
43
43
  ];
44
+ const jitodontfrontPubkeys = jitodontfrontAccounts.map(s => new web3_js_1.PublicKey(s));
45
+ const heliusTipPubkeys = helius_1.HELIUS_TIP_ACCOUNTS.map(s => new web3_js_1.PublicKey(s));
44
46
  function getJitoDontFrontAccount() {
45
- const randomIndex = Math.floor(Math.random() * jitodontfrontAccounts.length);
46
- return new web3_js_1.PublicKey(jitodontfrontAccounts[randomIndex]);
47
+ const randomIndex = Math.floor(Math.random() * jitodontfrontPubkeys.length);
48
+ return jitodontfrontPubkeys[randomIndex];
47
49
  }
48
50
  class SolTransactionBuilder {
49
51
  constructor(appConfig) {
@@ -88,6 +90,7 @@ class SolTransactionBuilder {
88
90
  return [];
89
91
  }
90
92
  buildTransactionForSwap(context, swapInstructions) {
93
+ const _t0 = Date.now();
91
94
  const max_block_offset = context.trade_runtime.settings.strategy.max_block_offset;
92
95
  const swapTx = new web3_js_1.Transaction();
93
96
  const preInstructions = this.getPreInstructions(context);
@@ -106,11 +109,14 @@ class SolTransactionBuilder {
106
109
  }
107
110
  let tip_instruction = web3_js_1.SystemProgram.transfer({
108
111
  fromPubkey: this.keypair.publicKey,
109
- toPubkey: new web3_js_1.PublicKey(helius_1.HELIUS_TIP_ACCOUNTS[Math.floor(Math.random() * helius_1.HELIUS_TIP_ACCOUNTS.length)]),
112
+ toPubkey: heliusTipPubkeys[Math.floor(Math.random() * heliusTipPubkeys.length)],
110
113
  lamports: tip_lamports,
111
114
  });
112
115
  swapTx.instructions.push(tip_instruction);
116
+ const _t1 = Date.now();
113
117
  swapTx.sign(this.keypair);
118
+ const _t2 = Date.now();
119
+ (0, dist_1.log_debug)(`[txBuilder] build breakdown: assemble=${_t1 - _t0}ms sign=${_t2 - _t1}ms total=${_t2 - _t0}ms`);
114
120
  return swapTx;
115
121
  }
116
122
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clonegod/ttd-sol-common",
3
- "version": "2.0.82",
3
+ "version": "2.0.84",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -16,6 +16,9 @@
16
16
  import { resolveTradeDirection, calculateStandardPrice } from '../../utils/trade_direction';
17
17
  import { report_data_to_analyze, QuoteTier } from '@clonegod/ttd-core';
18
18
 
19
+ /** USD 稳定币:作 quote 时直接按 $1,无需查价。扩展时在此加。 */
20
+ const USD_STABLECOINS = new Set(['USDT', 'USDC', 'USD1']);
21
+
19
22
  // ========== 类型定义 ==========
20
23
 
21
24
  interface CachedQuote {
@@ -441,25 +444,24 @@ export class QuotePriceVerify {
441
444
  ): string | void {
442
445
  if (inputAmountUi <= 0 || outputAmountUi <= 0) return;
443
446
 
444
- // 估算 USD 金额
445
- let swapUsd = 0;
446
- if (token0PriceUsd && token1PriceUsd && token0Address) {
447
- const inputIsToken0 = inputTokenAddress.toLowerCase() === token0Address.toLowerCase();
448
- swapUsd = inputIsToken0
449
- ? inputAmountUi * token0PriceUsd
450
- : inputAmountUi * token1PriceUsd;
451
- }
452
-
453
- // 判断是 买入 base 还是 卖出 base
447
+ // 判断 买入/卖出 base(USD 估值也要用 quote 侧,提前算)
454
448
  const direction = resolveTradeDirection(poolInfo, true);
455
449
  const baseToken = direction.baseToken;
456
450
  const quoteToken = direction.quoteToken;
457
451
 
458
452
  const inputIsQuoteToken = inputTokenAddress.toLowerCase() === quoteToken.address.toLowerCase();
459
453
  const isBuy = inputIsQuoteToken;
460
-
461
454
  const side = isBuy ? 'BUY' : 'SELL';
462
455
 
456
+ // 估算 USD:只看 **quote 侧那条腿**(swap 必有一条 quote 腿,quote 是稳定/可靠定价侧)。
457
+ // quote 是 USD 稳定币 → 直接按 $1;否则(SOL 等)→ 用 quote 市价。base(pump 币)有没有价都不影响。
458
+ const quoteIsToken0 = quoteToken.address === token0Address; // base58 原值比较(不 lowercase)
459
+ const quotePriceUsd = USD_STABLECOINS.has((quoteToken.symbol || '').toUpperCase())
460
+ ? 1
461
+ : (quoteIsToken0 ? (token0PriceUsd || 0) : (token1PriceUsd || 0));
462
+ const quoteLegAmount = isBuy ? inputAmountUi : outputAmountUi; // 买:input=quote;卖:output=quote
463
+ const swapUsd = quotePriceUsd > 0 ? quoteLegAmount * quotePriceUsd : 0;
464
+
463
465
  if (refPrice <= 0 || execPriceNum <= 0) return;
464
466
 
465
467
  // sign 约定:(ref - exec) / ref —— "我们报价 vs 实际成交"
@@ -470,7 +472,7 @@ export class QuotePriceVerify {
470
472
  const absDiffBps = Math.abs(diffBps);
471
473
  // 阈值统一:<5 ✅ / 5-10 ⚠️ / ≥10 ❌(前端颜色阈值同步)
472
474
  const status = absDiffBps < 5 ? '✅' : absDiffBps < 10 ? '⚠️' : '❌';
473
- const usdStr = swapUsd > 0 ? `$${swapUsd.toFixed(0)}` : '$?';
475
+ const usdStr = swapUsd > 0 ? `$${swapUsd.toFixed(2)}` : '$?';
474
476
 
475
477
  // USD 范围标注(不过滤,全部打印)
476
478
  // 规则:仅排除"过大的 swap"(超过 2× 询价金额),偏差大可能是滑点而非报价不准;
@@ -509,7 +511,7 @@ export class QuotePriceVerify {
509
511
  ref_price: refPrice,
510
512
  exec_price: execPriceNum,
511
513
  diff_bps: parseFloat(diffBps.toFixed(1)),
512
- swap_usd: parseFloat(swapUsd.toFixed(0)),
514
+ swap_usd: parseFloat(swapUsd.toFixed(2)), // 显示到分:pump 币多是 <$1 的小单,取整会全成 $0
513
515
  in_range: inRange,
514
516
  input_amount: inputAmountUi,
515
517
  output_amount: outputAmountUi,
@@ -1,4 +1,4 @@
1
- import { CHAIN_ID, TradeContext } from "@clonegod/ttd-core/dist";
1
+ import { CHAIN_ID, log_debug, TradeContext } from "@clonegod/ttd-core/dist";
2
2
  import { ComputeBudgetProgram, Connection, Keypair, LAMPORTS_PER_SOL, PublicKey, SystemProgram, Transaction, TransactionInstruction } from "@solana/web3.js";
3
3
  import { LAMPORTS_PER_MICRO_LAMPORTS } from "../common";
4
4
  import { SolanaBlockMetaUpdateEvent } from "../types";
@@ -55,9 +55,13 @@ const jitodontfrontAccounts = [
55
55
  'jitodontfront111111111111234565432123456RX5',
56
56
  ]
57
57
 
58
+ // 固定地址预构 PublicKey(避免每笔交易 base58 解码;模块加载时一次性)
59
+ const jitodontfrontPubkeys = jitodontfrontAccounts.map(s => new PublicKey(s));
60
+ const heliusTipPubkeys = HELIUS_TIP_ACCOUNTS.map(s => new PublicKey(s));
61
+
58
62
  function getJitoDontFrontAccount(): PublicKey {
59
- const randomIndex = Math.floor(Math.random() * jitodontfrontAccounts.length);
60
- return new PublicKey(jitodontfrontAccounts[randomIndex]);
63
+ const randomIndex = Math.floor(Math.random() * jitodontfrontPubkeys.length);
64
+ return jitodontfrontPubkeys[randomIndex];
61
65
  }
62
66
 
63
67
 
@@ -157,6 +161,7 @@ export class SolTransactionBuilder {
157
161
  * @returns
158
162
  */
159
163
  buildTransactionForSwap(context: TradeContext, swapInstructions: TransactionInstruction[]): Transaction {
164
+ const _t0 = Date.now()
160
165
  const max_block_offset = context.trade_runtime.settings.strategy.max_block_offset
161
166
  // console.log(`buildTransactionForSwap, max_block_offset: ${max_block_offset}`)
162
167
 
@@ -185,12 +190,16 @@ export class SolTransactionBuilder {
185
190
  }
186
191
  let tip_instruction = SystemProgram.transfer({
187
192
  fromPubkey: this.keypair.publicKey,
188
- toPubkey: new PublicKey(HELIUS_TIP_ACCOUNTS[Math.floor(Math.random() * HELIUS_TIP_ACCOUNTS.length)]),
193
+ toPubkey: heliusTipPubkeys[Math.floor(Math.random() * heliusTipPubkeys.length)],
189
194
  lamports: tip_lamports,
190
195
  })
191
196
  swapTx.instructions.push(tip_instruction)
192
197
 
193
- swapTx.sign(this.keypair)
198
+ const _t1 = Date.now()
199
+ swapTx.sign(this.keypair) // = compileMessage(serialize) + ed25519(tweetnacl) 签名
200
+ const _t2 = Date.now()
201
+ // 耗时拆分(debug 级,不刷屏):assemble=组装指令+设字段;sign=编译消息+ed25519 签名
202
+ log_debug(`[txBuilder] build breakdown: assemble=${_t1 - _t0}ms sign=${_t2 - _t1}ms total=${_t2 - _t0}ms`)
194
203
 
195
204
  return swapTx
196
205
  }