@clonegod/ttd-sol-common 2.0.49 → 2.0.51

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.51",
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
@@ -48,9 +103,12 @@ export class SolTransactionBuilder {
48
103
  // console.log('getPreInstructions', { cu_limit, sol_priority_fee_lamports, priorityFeeMicroLamports, })
49
104
 
50
105
  // set compute budget instruction
51
- const computeBudgetInstruction = ComputeBudgetProgram.setComputeUnitLimit({
52
- units: cu_limit,
53
- })
106
+ // const computeBudgetInstruction = ComputeBudgetProgram.setComputeUnitLimit({
107
+ // units: cu_limit,
108
+ // })
109
+
110
+ // set compute budget instruction with jitodontfront
111
+ const computeBudgetInstruction = this.createComputeUnitLimitWithJitoDontFront(cu_limit)
54
112
 
55
113
  // set priority fee instruction
56
114
  const priorityFeeInstruction = ComputeBudgetProgram.setComputeUnitPrice({
@@ -60,7 +118,37 @@ export class SolTransactionBuilder {
60
118
  return [computeBudgetInstruction, priorityFeeInstruction]
61
119
  }
62
120
 
63
-
121
+ /**
122
+ * 创建带有 jitodontfront 账户的 SetComputeUnitLimit 指令
123
+ * 将 jitodontfront 账户直接添加到 Compute Budget 指令中,用于防止三明治攻击
124
+ * 参考:
125
+ * - https://docs.jito.wtf/lowlatencytxnsend/#sandwich-mitigation
126
+ *
127
+ * 重要说明:
128
+ * 1. 包含 jitodontfront 账户的交易必须在 bundle 的第一个位置(索引 0)
129
+ * 2. 账户标记为只读(isWritable: false)以优化落地速度
130
+ * 3. 账户不需要在链上存在,但必须是有效的 pubkey
131
+ * 4. (可选)可以通过环境变量 JITO_DONT_FRONT_ACCOUNT 使用唯一的变体
132
+ */
133
+ private createComputeUnitLimitWithJitoDontFront(units: number): TransactionInstruction {
134
+ const jitoDontFrontAccount = getJitoDontFrontAccount();
135
+
136
+ // 构造 Compute Budget SetComputeUnitLimit 指令数据
137
+ // 1 字节鉴别符(2 表示 SetComputeUnitLimit)+ 4 字节 units(小端序)
138
+ const data = Buffer.alloc(5);
139
+ data.writeUInt8(2, 0); // 鉴别符:2 表示 SetComputeUnitLimit
140
+ data.writeUInt32LE(units, 1); // 设置计算单元(小端序)
141
+
142
+ return new TransactionInstruction({
143
+ keys: [
144
+ { pubkey: jitoDontFrontAccount, isSigner: false, isWritable: false }, // jitodontfront 账户,标记为只读
145
+ ],
146
+ programId: ComputeBudgetProgram.programId, // Compute Budget 程序 ID
147
+ data: data,
148
+ });
149
+ }
150
+
151
+
64
152
  // post-instructions
65
153
  private getPostInstructions(context: TradeContext): TransactionInstruction[] {
66
154
  return []
@@ -87,21 +175,21 @@ export class SolTransactionBuilder {
87
175
  swapTx.lastValidBlockHeight = this.recentBlockheight + max_block_offset
88
176
  swapTx.feePayer = this.keypair.publicKey
89
177
 
90
- const {sol_bundle_only, sol_tip_fee} = context.trade_runtime.settings.strategy
178
+ const { sol_bundle_only, sol_tip_fee } = context.trade_runtime.settings.strategy
91
179
 
92
180
  // sol_bundle_only = false, 使用 Helius Sender
93
181
  // sol_bundle_only = true, 使用 Jito Bundle - 不需要给Helius小费
94
- if(!sol_bundle_only) {
182
+ if (!sol_bundle_only) {
95
183
  // 使用 Helius Sender:
96
184
  // 1、swqos_only: 至少 5000 lamports 小费
97
185
  // -> transaction must send a tip of at least 5000 lamports to one of the following Helius wallets: [xxx, ...]
98
186
  // 2、swqos + jito: 至少 0.0002 SOL 小费 -> lamports = 0.0002 * LAMPORTS_PER_SOL
99
187
  // -> Requires minimum 0.0002 SOL tip.
100
188
  let tip_lamports = sol_tip_fee
101
- if(tip_lamports < 5000) {
189
+ if (tip_lamports < 5000) {
102
190
  tip_lamports = 5000
103
191
  }
104
- if(tip_lamports > 300000) {
192
+ if (tip_lamports > 300000) {
105
193
  tip_lamports = 300000
106
194
  }
107
195
  let tip_instruction = SystemProgram.transfer({
@@ -127,19 +215,19 @@ export class SolTransactionBuilder {
127
215
  const max_block_offset = context.trade_runtime.settings.strategy.max_block_offset
128
216
 
129
217
  let tipPayer = this.jitoTipWalletManager.getNextWallet(groupId)
130
- if(!tipPayer) {
218
+ if (!tipPayer) {
131
219
  tipPayer = this.keypair
132
220
  }
133
221
 
134
222
  let tipAccount = getJitoTipAccount()
135
223
  let tip_lamports = context.trade_runtime.settings.strategy.sol_tip_fee
136
- if(tip_lamports < 5000) {
224
+ if (tip_lamports < 5000) {
137
225
  tip_lamports = 5000
138
226
  }
139
- if(tip_lamports > 300000) {
227
+ if (tip_lamports > 300000) {
140
228
  tip_lamports = 300000
141
229
  }
142
-
230
+
143
231
  const jitoTipTx = new Transaction();
144
232
  jitoTipTx.add(
145
233
  SystemProgram.transfer({