@clonegod/ttd-sol-common 2.0.83 → 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(
|
|
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(
|
|
232
|
+
swap_usd: parseFloat(swapUsd.toFixed(2)),
|
|
233
233
|
in_range: inRange,
|
|
234
234
|
input_amount: inputAmountUi,
|
|
235
235
|
output_amount: outputAmountUi,
|
package/dist/trade/tx_builder.js
CHANGED
|
@@ -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() *
|
|
46
|
-
return
|
|
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:
|
|
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
|
@@ -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
|
-
//
|
|
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(
|
|
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(
|
|
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,
|
package/src/trade/tx_builder.ts
CHANGED
|
@@ -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() *
|
|
60
|
-
return
|
|
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:
|
|
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
|
-
|
|
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
|
}
|