@clonegod/ttd-sol-common 2.0.49 → 2.0.50

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.
@@ -13,6 +13,7 @@ export declare class SolTransactionBuilder {
13
13
  init(): Promise<void>;
14
14
  private handleBlockUpdateEvent;
15
15
  private getPreInstructions;
16
+ private createComputeUnitLimitWithJitoDontFront;
16
17
  private getPostInstructions;
17
18
  buildTransactionForSwap(context: TradeContext, swapInstructions: TransactionInstruction[]): Transaction;
18
19
  buildTransactionForTipJito(context: TradeContext): Transaction;
@@ -7,6 +7,46 @@ const common_1 = require("../common");
7
7
  const helius_1 = require("./send/helius");
8
8
  const jito_1 = require("./send/jito");
9
9
  const jito_tip_wallets_1 = require("./jito_tip_wallets");
10
+ const jitodontfrontAccounts = [
11
+ 'jitodontfront111111111111111111111111111111',
12
+ 'jitodontfront111111111111111111111111111123',
13
+ 'jitodontfront111111111111234565432123456782',
14
+ 'jitodontfront111111111111111111111111111118',
15
+ 'jitodontfront111111111111111111111111111183',
16
+ 'jitodontfront11111111111111111111111111111o',
17
+ 'jitodontfront1111111111111111111111111111of',
18
+ 'jitodontfront111111111111111111111111111116',
19
+ 'jitodontfront11111111111111111111111111116b',
20
+ 'jitodontfront11111111111111111111111111111a',
21
+ 'jitodontfront1111111111111111111111111111aJ',
22
+ 'jitodontfront11111111111111111111111111111J',
23
+ 'jitodontfront1111111111111111111111111111JR',
24
+ 'jitodontfront11111111111111111111111111111U',
25
+ 'jitodontfront1111111111111111111111111111UU',
26
+ 'jitodontfront11111111111111111111111111111g',
27
+ 'jitodontfront1111111111111111111111111111gt',
28
+ 'jitodontfront11111111111111111111111111111F',
29
+ 'jitodontfront1111111111111111111111111111Ff',
30
+ 'jitodontfront11111111111111111111111111111v',
31
+ 'jitodontfront1111111111111111111111111111vw',
32
+ 'jitodontfront1111111111111111111111111111UA',
33
+ 'jitodontfront111111111111111111111111111bcv',
34
+ 'jitodontfront111111111111111111111111111Svm',
35
+ 'jitodontfront111111111111111111111111111Zj2',
36
+ 'jitodontfront111111111111111111111111111wja',
37
+ 'jitodontfront111111111111111111111111111r3j',
38
+ 'jitodontfront111111111111111111111111111LAG',
39
+ 'jitodontfront111111111111111111111111111iej',
40
+ 'jitodontfront111111111111111111111111111mxb',
41
+ 'jitodontfront111111111111111111111111111m9D',
42
+ 'jitodontfront111111111111111111111111111rjQ',
43
+ 'jitodontfront1111111111111111111111111111wP',
44
+ 'jitodontfront111111111111234565432123456RX5',
45
+ ];
46
+ function getJitoDontFrontAccount() {
47
+ const randomIndex = Math.floor(Math.random() * jitodontfrontAccounts.length);
48
+ return new web3_js_1.PublicKey(jitodontfrontAccounts[randomIndex]);
49
+ }
10
50
  class SolTransactionBuilder {
11
51
  constructor(appConfig) {
12
52
  this.appConfig = appConfig;
@@ -28,14 +68,25 @@ class SolTransactionBuilder {
28
68
  const cu_limit = context.pool_info.cu_limit || 600000;
29
69
  const sol_priority_fee_lamports = context.trade_runtime.settings.strategy.sol_priority_fee;
30
70
  const priorityFeeMicroLamports = Math.floor((sol_priority_fee_lamports * common_1.LAMPORTS_PER_MICRO_LAMPORTS) / cu_limit);
31
- const computeBudgetInstruction = web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
32
- units: cu_limit,
33
- });
71
+ const computeBudgetInstruction = this.createComputeUnitLimitWithJitoDontFront(cu_limit);
34
72
  const priorityFeeInstruction = web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
35
73
  microLamports: priorityFeeMicroLamports,
36
74
  });
37
75
  return [computeBudgetInstruction, priorityFeeInstruction];
38
76
  }
77
+ createComputeUnitLimitWithJitoDontFront(units) {
78
+ const jitoDontFrontAccount = getJitoDontFrontAccount();
79
+ const data = Buffer.alloc(5);
80
+ data.writeUInt8(2, 0);
81
+ data.writeUInt32LE(units, 1);
82
+ return new web3_js_1.TransactionInstruction({
83
+ keys: [
84
+ { pubkey: jitoDontFrontAccount, isSigner: false, isWritable: false },
85
+ ],
86
+ programId: web3_js_1.ComputeBudgetProgram.programId,
87
+ data: data,
88
+ });
89
+ }
39
90
  getPostInstructions(context) {
40
91
  return [];
41
92
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clonegod/ttd-sol-common",
3
- "version": "2.0.49",
3
+ "version": "2.0.50",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "types/index.d.ts",
@@ -7,6 +7,61 @@ import { HELIUS_TIP_ACCOUNTS } from "./send/helius";
7
7
  import { getJitoTipAccount } from "./send/jito";
8
8
  import { JitoTipWalletManager } from "./jito_tip_wallets";
9
9
 
10
+ /**
11
+ * Jito Sandwich Mitigation: jitodontfront 账户
12
+ * 用于防止三明治攻击,包含此账户的交易必须在 bundle 的第一个位置(索引 0)
13
+ * 参考: https://docs.jito.wtf/lowlatencytxnsend/#sandwich-mitigation
14
+ *
15
+ * 重要说明:
16
+ * 1. 账户不需要在链上存在,但必须是有效的 pubkey
17
+ * 2. 账户应标记为只读(isWritable: false)以优化落地速度
18
+ * 3. (可选)可以使用唯一的 jitodontfront 变体用于应用程序
19
+ *
20
+ * 可以通过环境变量 JITO_DONT_FRONT_ACCOUNT 自定义账户,否则从默认列表中随机选择
21
+ */
22
+
23
+ const jitodontfrontAccounts = [
24
+ 'jitodontfront111111111111111111111111111111',
25
+ 'jitodontfront111111111111111111111111111123',
26
+ 'jitodontfront111111111111234565432123456782',
27
+ 'jitodontfront111111111111111111111111111118',
28
+ 'jitodontfront111111111111111111111111111183',
29
+ 'jitodontfront11111111111111111111111111111o',
30
+ 'jitodontfront1111111111111111111111111111of',
31
+ 'jitodontfront111111111111111111111111111116',
32
+ 'jitodontfront11111111111111111111111111116b',
33
+ 'jitodontfront11111111111111111111111111111a',
34
+ 'jitodontfront1111111111111111111111111111aJ',
35
+ 'jitodontfront11111111111111111111111111111J',
36
+ 'jitodontfront1111111111111111111111111111JR',
37
+ 'jitodontfront11111111111111111111111111111U',
38
+ 'jitodontfront1111111111111111111111111111UU',
39
+ 'jitodontfront11111111111111111111111111111g',
40
+ 'jitodontfront1111111111111111111111111111gt',
41
+ 'jitodontfront11111111111111111111111111111F',
42
+ 'jitodontfront1111111111111111111111111111Ff',
43
+ 'jitodontfront11111111111111111111111111111v',
44
+ 'jitodontfront1111111111111111111111111111vw',
45
+ 'jitodontfront1111111111111111111111111111UA',
46
+ 'jitodontfront111111111111111111111111111bcv',
47
+ 'jitodontfront111111111111111111111111111Svm',
48
+ 'jitodontfront111111111111111111111111111Zj2',
49
+ 'jitodontfront111111111111111111111111111wja',
50
+ 'jitodontfront111111111111111111111111111r3j',
51
+ 'jitodontfront111111111111111111111111111LAG',
52
+ 'jitodontfront111111111111111111111111111iej',
53
+ 'jitodontfront111111111111111111111111111mxb',
54
+ 'jitodontfront111111111111111111111111111m9D',
55
+ 'jitodontfront111111111111111111111111111rjQ',
56
+ 'jitodontfront1111111111111111111111111111wP',
57
+ 'jitodontfront111111111111234565432123456RX5',
58
+ ]
59
+
60
+ function getJitoDontFrontAccount(): PublicKey {
61
+ const randomIndex = Math.floor(Math.random() * jitodontfrontAccounts.length);
62
+ return new PublicKey(jitodontfrontAccounts[randomIndex]);
63
+ }
64
+
10
65
 
11
66
  export class SolTransactionBuilder {
12
67
  appConfig: SolanaTradeAppConfig
@@ -47,10 +102,8 @@ export class SolTransactionBuilder {
47
102
  const priorityFeeMicroLamports = Math.floor((sol_priority_fee_lamports * LAMPORTS_PER_MICRO_LAMPORTS) / cu_limit)
48
103
  // console.log('getPreInstructions', { cu_limit, sol_priority_fee_lamports, priorityFeeMicroLamports, })
49
104
 
50
- // set compute budget instruction
51
- const computeBudgetInstruction = ComputeBudgetProgram.setComputeUnitLimit({
52
- units: cu_limit,
53
- })
105
+ // set compute budget instruction with jitodontfront
106
+ const computeBudgetInstruction = this.createComputeUnitLimitWithJitoDontFront(cu_limit)
54
107
 
55
108
  // set priority fee instruction
56
109
  const priorityFeeInstruction = ComputeBudgetProgram.setComputeUnitPrice({
@@ -60,7 +113,37 @@ export class SolTransactionBuilder {
60
113
  return [computeBudgetInstruction, priorityFeeInstruction]
61
114
  }
62
115
 
63
-
116
+ /**
117
+ * 创建带有 jitodontfront 账户的 SetComputeUnitLimit 指令
118
+ * 将 jitodontfront 账户直接添加到 Compute Budget 指令中,用于防止三明治攻击
119
+ * 参考:
120
+ * - https://docs.jito.wtf/lowlatencytxnsend/#sandwich-mitigation
121
+ *
122
+ * 重要说明:
123
+ * 1. 包含 jitodontfront 账户的交易必须在 bundle 的第一个位置(索引 0)
124
+ * 2. 账户标记为只读(isWritable: false)以优化落地速度
125
+ * 3. 账户不需要在链上存在,但必须是有效的 pubkey
126
+ * 4. (可选)可以通过环境变量 JITO_DONT_FRONT_ACCOUNT 使用唯一的变体
127
+ */
128
+ private createComputeUnitLimitWithJitoDontFront(units: number): TransactionInstruction {
129
+ const jitoDontFrontAccount = getJitoDontFrontAccount();
130
+
131
+ // 构造 Compute Budget SetComputeUnitLimit 指令数据
132
+ // 1 字节鉴别符(2 表示 SetComputeUnitLimit)+ 4 字节 units(小端序)
133
+ const data = Buffer.alloc(5);
134
+ data.writeUInt8(2, 0); // 鉴别符:2 表示 SetComputeUnitLimit
135
+ data.writeUInt32LE(units, 1); // 设置计算单元(小端序)
136
+
137
+ return new TransactionInstruction({
138
+ keys: [
139
+ { pubkey: jitoDontFrontAccount, isSigner: false, isWritable: false }, // jitodontfront 账户,标记为只读
140
+ ],
141
+ programId: ComputeBudgetProgram.programId, // Compute Budget 程序 ID
142
+ data: data,
143
+ });
144
+ }
145
+
146
+
64
147
  // post-instructions
65
148
  private getPostInstructions(context: TradeContext): TransactionInstruction[] {
66
149
  return []
@@ -87,21 +170,21 @@ export class SolTransactionBuilder {
87
170
  swapTx.lastValidBlockHeight = this.recentBlockheight + max_block_offset
88
171
  swapTx.feePayer = this.keypair.publicKey
89
172
 
90
- const {sol_bundle_only, sol_tip_fee} = context.trade_runtime.settings.strategy
173
+ const { sol_bundle_only, sol_tip_fee } = context.trade_runtime.settings.strategy
91
174
 
92
175
  // sol_bundle_only = false, 使用 Helius Sender
93
176
  // sol_bundle_only = true, 使用 Jito Bundle - 不需要给Helius小费
94
- if(!sol_bundle_only) {
177
+ if (!sol_bundle_only) {
95
178
  // 使用 Helius Sender:
96
179
  // 1、swqos_only: 至少 5000 lamports 小费
97
180
  // -> transaction must send a tip of at least 5000 lamports to one of the following Helius wallets: [xxx, ...]
98
181
  // 2、swqos + jito: 至少 0.0002 SOL 小费 -> lamports = 0.0002 * LAMPORTS_PER_SOL
99
182
  // -> Requires minimum 0.0002 SOL tip.
100
183
  let tip_lamports = sol_tip_fee
101
- if(tip_lamports < 5000) {
184
+ if (tip_lamports < 5000) {
102
185
  tip_lamports = 5000
103
186
  }
104
- if(tip_lamports > 300000) {
187
+ if (tip_lamports > 300000) {
105
188
  tip_lamports = 300000
106
189
  }
107
190
  let tip_instruction = SystemProgram.transfer({
@@ -127,19 +210,19 @@ export class SolTransactionBuilder {
127
210
  const max_block_offset = context.trade_runtime.settings.strategy.max_block_offset
128
211
 
129
212
  let tipPayer = this.jitoTipWalletManager.getNextWallet(groupId)
130
- if(!tipPayer) {
213
+ if (!tipPayer) {
131
214
  tipPayer = this.keypair
132
215
  }
133
216
 
134
217
  let tipAccount = getJitoTipAccount()
135
218
  let tip_lamports = context.trade_runtime.settings.strategy.sol_tip_fee
136
- if(tip_lamports < 5000) {
219
+ if (tip_lamports < 5000) {
137
220
  tip_lamports = 5000
138
221
  }
139
- if(tip_lamports > 300000) {
222
+ if (tip_lamports > 300000) {
140
223
  tip_lamports = 300000
141
224
  }
142
-
225
+
143
226
  const jitoTipTx = new Transaction();
144
227
  jitoTipTx.add(
145
228
  SystemProgram.transfer({