100x-sdk 1.0.2 → 1.0.4

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.
@@ -4,74 +4,63 @@ const Decimal = require('decimal.js');
4
4
 
5
5
 
6
6
  /**
7
- * 计算代币买入时的流动性影响 Calculate liquidity impact for token buy operations
8
- *
9
- * 此函数分析买入操作对价格区间内流动性的影响,计算可用的自由流动性、锁定流动性,
10
- * 并支持跳过指定订单(将其流动性视为可用)。适用于做多订单(up_orders)场景。
7
+ * Calculate liquidity impact for token buy operations
8
+ *
11
9
  * This function analyzes the liquidity impact of buy operations within price ranges,
12
10
  * calculates available free liquidity, locked liquidity, and supports skipping specific
13
11
  * orders (treating their liquidity as available). Applicable for long orders (up_orders) scenarios.
14
- *
15
- * @param {bigint|string|number} price - 当前代币价格,作为计算起始价格 Current token price, used as calculation start price
16
- * @param {bigint|string|number} buyTokenAmount - 购买的代币数量,目标买入数量 Amount of tokens to buy, target purchase amount
17
- * @param {Array<Object>} orders - 订单数组,按 lock_lp_start_price 从小到大排序 Array of orders sorted by lock_lp_start_price (ascending):
18
- * - order_type: {number} 订单类型(1=做多,2=做空) Order type (1=long, 2=short)
19
- * - mint: {string} 代币地址 Token mint address
20
- * - user: {string} 用户地址 User address
21
- * - lock_lp_start_price: {string} LP锁定开始价格 LP lock start price (required)
22
- * - lock_lp_end_price: {string} LP锁定结束价格 LP lock end price (required)
23
- * - lock_lp_sol_amount: {number} 锁定的SOL数量 Locked SOL amount (required)
24
- * - lock_lp_token_amount: {number} 锁定的代币数量 Locked token amount (required)
25
- * - start_time: {number} 开始时间戳 Start timestamp
26
- * - end_time: {number} 结束时间戳 End timestamp
27
- * - margin_sol_amount: {number} 保证金SOL数量 Margin SOL amount
28
- * - borrow_amount: {number} 借贷数量 Borrow amount
29
- * - position_asset_amount: {number} 持仓资产数量 Position asset amount
30
- * - borrow_fee: {number} 借贷费用 Borrow fee
31
- * - order_pda: {string} 订单PDA地址 Order PDA address (required for passOrder matching)
32
- * @param {number} onceMaxOrder - 一次处理的最大订单数,限制遍历范围 Maximum orders to process at once, limits traversal range
33
- * @param {string|null} passOrder - 需要跳过的订单PDA地址字符串,当该值与订单的order_pda匹配时,跳过该订单并将其流动性计入自由流动性 Order PDA address string to skip, when this value matches an order's order_pda, skip that order and count its liquidity as free liquidity
34
- *
35
- * @returns {Object} 流动性计算结果对象,包含详细的流动性分析数据 Liquidity calculation result object with detailed liquidity analysis data:
36
- *
37
- * **自由流动性 Free Liquidity:**
38
- * - free_lp_sol_amount_sum: {bigint} 可用自由流动性SOL总量,包含以下来源:1)价格间隙流动性 2)跳过订单的流动性 3)无限流动性(如有)
39
- * Total available free liquidity SOL amount, includes: 1) price gap liquidity 2) skipped order liquidity 3) infinite liquidity (if any)
40
- * - free_lp_token_amount_sum: {bigint} 可用自由流动性Token总量,与SOL对应,表示在不强平任何订单情况下可买到的最大代币数量
41
- * Total available free liquidity token amount, corresponds to SOL, represents max tokens buyable without force closing any orders
42
- *
43
- * **锁定流动性 Locked Liquidity:**
44
- * - lock_lp_sol_amount_sum: {bigint} 被锁定的流动性SOL总量,不包括跳过的订单,这部分流动性不可直接使用
45
- * Total locked liquidity SOL amount, excludes skipped orders, this liquidity is not directly usable
46
- * - lock_lp_token_amount_sum: {bigint} 被锁定的流动性Token总量,不包括跳过的订单,对应于锁定的SOL流动性
47
- * Total locked liquidity token amount, excludes skipped orders, corresponds to locked SOL liquidity
48
- *
49
- * **流动性状态标识 Liquidity Status Indicators:**
50
- * - has_infinite_lp: {boolean} 是否包含无限流动性,true表示订单链表已结束且计算了到最大价格(MAX_U128_PRICE)的流动性
51
- * Whether includes infinite liquidity, true means order chain ended and liquidity to max price (MAX_U128_PRICE) was calculated
52
- * - pass_order_id: {number} 被跳过的订单在数组中的索引位置,-1表示没有跳过任何订单,>=0表示跳过了对应索引的订单
53
- * Index of skipped order in array, -1 means no order skipped, >=0 means order at that index was skipped
54
- *
55
- * **买入执行信息 Buy Execution Info:**
56
- * - force_close_num: {number} 需要强平的订单数量,表示为了买到目标数量需要强制平仓多少个订单,0表示无需强平
57
- * Number of orders that need to be force closed, indicates how many orders need force closure to buy target amount, 0 means no force closure needed
58
- * - ideal_lp_sol_amount: {bigint} 理想SOL使用量,基于当前价格使用CurveAMM直接计算的理论最小SOL需求,不考虑流动性分布
59
- * Ideal SOL usage, theoretical minimum SOL requirement calculated directly from current price using CurveAMM, ignores liquidity distribution
60
- * - real_lp_sol_amount: {bigint} 实际SOL使用量,考虑真实流动性分布的精确SOL需求。0表示当前自由流动性不足以满足买入需求,需要强平更多订单
61
- * Actual SOL usage, precise SOL requirement considering real liquidity distribution. 0 means current free liquidity insufficient for buy requirement, need to force close more orders
62
- *
63
- * @throws {Error} 参数验证错误:price、buyTokenAmount、orders、onceMaxOrder 参数无效 Parameter validation error: invalid price, buyTokenAmount, orders, or onceMaxOrder
64
- * @throws {Error} 价格转换错误:无法将价格参数转换为 BigInt Price conversion error: cannot convert price parameters to BigInt
65
- * @throws {Error} 流动性计算错误:CurveAMM 计算失败或数值转换错误 Liquidity calculation error: CurveAMM calculation failure or value conversion error
66
- * @throws {Error} 间隙流动性计算失败:价格间隙流动性计算异常 Gap liquidity calculation failure: price gap liquidity calculation exception
67
- * @throws {Error} 无限流动性计算失败:最大价格流动性计算异常 Infinite liquidity calculation failure: max price liquidity calculation exception
68
- * @throws {Error} 订单数据格式错误:订单对象缺少必需字段 Order data format error: order object missing required fields
12
+ *
13
+ * @param {bigint|string|number} price - Current token price, used as calculation start price
14
+ * @param {bigint|string|number} buyTokenAmount - Amount of tokens to buy, target purchase amount
15
+ * @param {Array<Object>} orders - Array of orders sorted by lock_lp_start_price (ascending):
16
+ * - order_type: {number} Order type (1=long, 2=short)
17
+ * - mint: {string} Token mint address
18
+ * - user: {string} User address
19
+ * - lock_lp_start_price: {string} LP lock start price (required)
20
+ * - lock_lp_end_price: {string} LP lock end price (required)
21
+ * - lock_lp_sol_amount: {number} Locked SOL amount (required)
22
+ * - lock_lp_token_amount: {number} Locked token amount (required)
23
+ * - start_time: {number} Start timestamp
24
+ * - end_time: {number} End timestamp
25
+ * - margin_sol_amount: {number} Margin SOL amount
26
+ * - borrow_amount: {number} Borrow amount
27
+ * - position_asset_amount: {number} Position asset amount
28
+ * - borrow_fee: {number} Borrow fee
29
+ * - order_pda: {string} Order PDA address (required for passOrder matching)
30
+ * @param {number} onceMaxOrder - Maximum orders to process at once, limits traversal range
31
+ * @param {string|null} passOrder - Order PDA address string to skip, when this value matches an order's order_pda, skip that order and count its liquidity as free liquidity
32
+ *
33
+ * @returns {Object} Liquidity calculation result object with detailed liquidity analysis data:
34
+ *
35
+ * **Free Liquidity:**
36
+ * - free_lp_sol_amount_sum: {bigint} Total available free liquidity SOL amount, includes: 1) price gap liquidity 2) skipped order liquidity 3) infinite liquidity (if any)
37
+ * - free_lp_token_amount_sum: {bigint} Total available free liquidity token amount, corresponds to SOL, represents max tokens buyable without force closing any orders
38
+ *
39
+ * **Locked Liquidity:**
40
+ * - lock_lp_sol_amount_sum: {bigint} Total locked liquidity SOL amount, excludes skipped orders, this liquidity is not directly usable
41
+ * - lock_lp_token_amount_sum: {bigint} Total locked liquidity token amount, excludes skipped orders, corresponds to locked SOL liquidity
42
+ *
43
+ * **Liquidity Status Indicators:**
44
+ * - has_infinite_lp: {boolean} Whether includes infinite liquidity, true means order chain ended and liquidity to max price (MAX_U128_PRICE) was calculated
45
+ * - pass_order_id: {number} Index of skipped order in array, -1 means no order skipped, >=0 means order at that index was skipped
46
+ *
47
+ * **Buy Execution Info:**
48
+ * - force_close_num: {number} Number of orders that need to be force closed, indicates how many orders need force closure to buy target amount, 0 means no force closure needed
49
+ * - ideal_lp_sol_amount: {bigint} Ideal SOL usage, theoretical minimum SOL requirement calculated directly from current price using CurveAMM, ignores liquidity distribution
50
+ * - real_lp_sol_amount: {bigint} Actual SOL usage, precise SOL requirement considering real liquidity distribution. 0 means current free liquidity insufficient for buy requirement, need to force close more orders
51
+ *
52
+ * @throws {Error} Parameter validation error: invalid price, buyTokenAmount, orders, or onceMaxOrder
53
+ * @throws {Error} Price conversion error: cannot convert price parameters to BigInt
54
+ * @throws {Error} Liquidity calculation error: CurveAMM calculation failure or value conversion error
55
+ * @throws {Error} Gap liquidity calculation failure: price gap liquidity calculation exception
56
+ * @throws {Error} Infinite liquidity calculation failure: max price liquidity calculation exception
57
+ * @throws {Error} Order data format error: order object missing required fields
69
58
  */
70
59
  function calcLiqTokenBuy(price, buyTokenAmount, orders, onceMaxOrder, passOrder = null, initialVirtualSol = null, initialVirtualToken = null) {
71
- // 由于是买入操作 肯定拿的是 up_orders 方向的 订单 lock_lp_start_price < lock_lp_end_price
72
- // 并且 lock_lp_start_price 在 orders 中是从小到大排序的
60
+ // Since this is a buy operation, the orders are definitely in the up_orders direction lock_lp_start_price < lock_lp_end_price
61
+ // And lock_lp_start_price is sorted in ascending order in orders
73
62
 
74
- // 参数验证
63
+ // Parameter validation
75
64
  if (!price && price !== 0) {
76
65
  throw new Error('参数验证错误:price 参数不能为空 Parameter validation error: price cannot be null');
77
66
  }
@@ -89,15 +78,15 @@ function calcLiqTokenBuy(price, buyTokenAmount, orders, onceMaxOrder, passOrder
89
78
  }
90
79
 
91
80
  const result = {
92
- free_lp_sol_amount_sum: 0n, // 间隙中可使用的sol流动性数量
93
- free_lp_token_amount_sum: 0n, // 间隙中可使用的token流动性数量
81
+ free_lp_sol_amount_sum: 0n, // Amount of SOL liquidity usable in the gaps
82
+ free_lp_token_amount_sum: 0n, // Amount of token liquidity usable in the gaps
94
83
  lock_lp_sol_amount_sum: 0n,
95
84
  lock_lp_token_amount_sum: 0n,
96
- has_infinite_lp: false, // 是否包含无限流动性
97
- pass_order_id: -1, // 跳过的订单索引
98
- force_close_num: 0, // 强平订单数量
99
- ideal_lp_sol_amount: 0n, // 理想情况下买到buyTokenAmount的数量, 理想情况下使用的SOL数量
100
- real_lp_sol_amount: 0n, // 要买到buyTokenAmount的数量, 实际使用的SOL数量
85
+ has_infinite_lp: false, // Whether includes infinite liquidity
86
+ pass_order_id: -1, // Index of skipped order
87
+ force_close_num: 0, // Number of force closed orders
88
+ ideal_lp_sol_amount: 0n, // Amount of SOL used to buy buyTokenAmount under ideal conditions
89
+ real_lp_sol_amount: 0n, // Amount of SOL actually used to buy buyTokenAmount
101
90
  }
102
91
 
103
92
 
@@ -110,7 +99,7 @@ function calcLiqTokenBuy(price, buyTokenAmount, orders, onceMaxOrder, passOrder
110
99
  throw new Error(`价格转换错误:无法将 buyTokenAmount 转换为 BigInt Price conversion error: Cannot convert buyTokenAmount to BigInt - ${error.message}`);
111
100
  }
112
101
 
113
- // 声明用于跟踪前一次自由流动性总量的变量
102
+ // Declare variable for tracking the previous free liquidity total
114
103
  let prev_free_lp_sol_amount_sum;
115
104
 
116
105
  //result.ideal_lp_token_amount_sum = buyTokenAmountBigInt;
@@ -126,13 +115,13 @@ function calcLiqTokenBuy(price, buyTokenAmount, orders, onceMaxOrder, passOrder
126
115
  initialVirtualSolDecimal,
127
116
  initialVirtualTokenDecimal
128
117
  );
129
- // console.log(`理想计算: 当前价格=${priceBigInt}, 目标代币=${buyTokenAmountBigInt}, 理想SOL=${result.ideal_lp_sol_amount}`);
118
+ // console.log(`ideal calculation: current price=${priceBigInt}, target token=${buyTokenAmountBigInt}, ideal SOL=${result.ideal_lp_sol_amount}`);
130
119
  } catch (error) {
131
120
  throw new Error(`buy流动性计算错误:理想流动性计算失败 Liquidity calculation error: Ideal liquidity calculation failed - ${error.message}`);
132
121
  }
133
122
 
134
123
 
135
- // orders 长度为0 时要单独计算
124
+ // orders length of 0 requires separate calculation
136
125
  if (orders.length === 0) {
137
126
 
138
127
 
@@ -154,14 +143,14 @@ function calcLiqTokenBuy(price, buyTokenAmount, orders, onceMaxOrder, passOrder
154
143
 
155
144
 
156
145
 
157
- // 选择较小值进行遍历
146
+ // Choose the smaller value for traversal
158
147
  const loopCount = Math.min(orders.length, onceMaxOrder);
159
148
 
160
149
  let counti = 0;
161
150
  for (let i = 0; i < loopCount; i++) {
162
151
  const order = orders[i];
163
152
 
164
- // 验证订单数据格式
153
+ // Validate order data format
165
154
  if (!order) {
166
155
  throw new Error(`订单数据格式错误:订单 ${i} 为空 Order data format error: Order ${i} is null`);
167
156
  }
@@ -173,15 +162,15 @@ function calcLiqTokenBuy(price, buyTokenAmount, orders, onceMaxOrder, passOrder
173
162
  }
174
163
 
175
164
 
176
- // 计算间隙流动性
165
+ // Calculate gap liquidity
177
166
  let startPrice, endPrice;
178
167
  try {
179
168
  if (i === 0) {
180
- // 第一个订单:使用当前价格到订单开始价格的间隙
169
+ // First order: use the gap from current price to order start price
181
170
  startPrice = BigInt(price);
182
171
  endPrice = BigInt(order.lock_lp_start_price);
183
172
  } else {
184
- // 后续订单:使用前一个订单结束价格到当前订单开始价格的间隙
173
+ // Subsequent orders: use the gap from previous order end price to current order start price
185
174
  startPrice = BigInt(orders[i - 1].lock_lp_end_price);
186
175
  endPrice = BigInt(order.lock_lp_start_price);
187
176
  }
@@ -190,7 +179,7 @@ function calcLiqTokenBuy(price, buyTokenAmount, orders, onceMaxOrder, passOrder
190
179
  }
191
180
 
192
181
 
193
- // 如果存在价格间隙,计算自由流动性
182
+ // If a price gap exists, calculate free liquidity
194
183
  if (endPrice > startPrice) {
195
184
  try {
196
185
  const initialVirtualSolDecimal = new Decimal(initialVirtualSol).div(CurveAMM.SOL_PRECISION_FACTOR_DECIMAL);
@@ -205,30 +194,30 @@ function calcLiqTokenBuy(price, buyTokenAmount, orders, onceMaxOrder, passOrder
205
194
  const [solAmount, tokenAmount] = gapLiquidity;
206
195
 
207
196
  try {
208
- prev_free_lp_sol_amount_sum = result.free_lp_sol_amount_sum; // 上次的值
197
+ prev_free_lp_sol_amount_sum = result.free_lp_sol_amount_sum; // Previous value
209
198
  result.free_lp_sol_amount_sum += BigInt(solAmount);
210
199
  result.free_lp_token_amount_sum += BigInt(tokenAmount);
211
- // console.log(`间隙[${i}]: ${startPrice}→${endPrice}, 间隙SOL=${solAmount}, 间隙Token=${tokenAmount}, 累计自由Token=${result.free_lp_token_amount_sum}`);
200
+ // console.log(`gap[${i}]: ${startPrice}→${endPrice}, gap SOL=${solAmount}, gap Token=${tokenAmount}, cumulative free Token=${result.free_lp_token_amount_sum}`);
212
201
  } catch (error) {
213
202
  throw new Error(`流动性计算错误:无法转换间隙流动性数值 Liquidity calculation error: Cannot convert gap liquidity values - ${error.message}`);
214
203
  }
215
204
 
216
205
 
217
- // 计算实际使用的SOL数量 到能买到为止
206
+ // Calculate the actual amount of SOL used, until enough can be bought
218
207
  if (result.real_lp_sol_amount === 0n) {
219
208
  if (result.free_lp_token_amount_sum > buyTokenAmountBigInt) {
220
- // 这时间隙流动性已经够买入的了
221
- // 计算最后精确需要买多少token
209
+ // At this point the gap liquidity is already enough to buy
210
+ // Calculate the final precise amount of token to buy
222
211
  try {
223
212
  const actualBuyAmount = buyTokenAmountBigInt - (result.free_lp_token_amount_sum - BigInt(tokenAmount));
224
213
  // console.log("actualBuyAmount",actualBuyAmount)
225
214
  const [, preciseSol] = CurveAMM.buyFromPriceWithTokenOutput(startPrice, actualBuyAmount)
226
215
  result.real_lp_sol_amount = prev_free_lp_sol_amount_sum + BigInt(preciseSol);
227
216
 
228
- // console.log(`实际计算[${i}]: 自由流动性已足够, actualBuyAmount=${actualBuyAmount}, preciseSol=${preciseSol}, 实际SOL=${result.real_lp_sol_amount}`);
229
- result.force_close_num = counti; // 强平订单数量
217
+ // console.log(`actual calculation[${i}]: free liquidity sufficient, actualBuyAmount=${actualBuyAmount}, preciseSol=${preciseSol}, actual SOL=${result.real_lp_sol_amount}`);
218
+ result.force_close_num = counti; // Number of force closed orders
230
219
  } catch (error) {
231
- // console.log('错误详情:', error);
220
+ // console.log('error details:', error);
232
221
  throw new Error(`流动性计算错误:精确SOL计算失败 Liquidity calculation error: Precise SOL calculation failed - ${error.message}`);
233
222
  }
234
223
  }
@@ -246,13 +235,13 @@ function calcLiqTokenBuy(price, buyTokenAmount, orders, onceMaxOrder, passOrder
246
235
  } else {
247
236
  }
248
237
 
249
- // 检查是否需要跳过该订单(passOrder 逻辑)
238
+ // Check whether this order needs to be skipped (passOrder logic)
250
239
  //const shouldSkipOrder = passOrder && typeof passOrder === 'string' && order.order_pda === passOrder;
251
240
 
252
241
 
253
242
  if (passOrder == order.order_pda) {
254
243
 
255
- // 将跳过订单的流动性加到自由流动性中
244
+ // Add the skipped order's liquidity to the free liquidity
256
245
  try {
257
246
  if (order.lock_lp_sol_amount === undefined || order.lock_lp_sol_amount === null) {
258
247
  throw new Error(`订单数据格式错误:跳过订单 ${i} 缺少 lock_lp_sol_amount Order data format error: Skipped order ${i} missing lock_lp_sol_amount`);
@@ -261,25 +250,25 @@ function calcLiqTokenBuy(price, buyTokenAmount, orders, onceMaxOrder, passOrder
261
250
  throw new Error(`订单数据格式错误:跳过订单 ${i} 缺少 lock_lp_token_amount Order data format error: Skipped order ${i} missing lock_lp_token_amount`);
262
251
  }
263
252
 
264
- const prevFreeSolSum = result.free_lp_sol_amount_sum; // 保存之前的值用于计算
253
+ const prevFreeSolSum = result.free_lp_sol_amount_sum; // Save the previous value for calculation
265
254
  result.free_lp_sol_amount_sum += BigInt(order.lock_lp_sol_amount);
266
255
  result.free_lp_token_amount_sum += BigInt(order.lock_lp_token_amount);
267
256
 
268
257
  result.pass_order_id = i;
269
258
 
270
259
 
271
- // 检查跳过订单后的自由流动性是否已满足买入需求
260
+ // Check whether the free liquidity after skipping the order already meets the buy requirement
272
261
  if (result.real_lp_sol_amount === 0n) {
273
262
  if (result.free_lp_token_amount_sum >= buyTokenAmountBigInt) {
274
- // 自由流动性已经够买入需求了
263
+ // Free liquidity is already enough for the buy requirement
275
264
  try {
276
265
  //const remainingToken = result.free_lp_token_amount_sum - buyTokenAmountBigInt;
277
- // 从当前价格开始计算需要多少SOL来买到精确的token数量
266
+ // Calculate from the current price how much SOL is needed to buy the precise token amount
278
267
  const targetPrice = i === 0 ? BigInt(price) : BigInt(orders[i - 1].lock_lp_end_price);
279
268
  const actualBuyAmount = buyTokenAmountBigInt - (result.free_lp_token_amount_sum - BigInt(order.lock_lp_token_amount));
280
269
  const [, preciseSol] = CurveAMM.buyFromPriceWithTokenOutput(targetPrice, actualBuyAmount);
281
270
  result.real_lp_sol_amount = prevFreeSolSum + BigInt(preciseSol);
282
- // console.log(`实际计算[${i}]: 跳过订单后足够, targetPrice=${targetPrice}, preciseSol=${preciseSol}, 实际SOL=${result.real_lp_sol_amount}`);
271
+ // console.log(`actual calculation[${i}]: sufficient after skipping order, targetPrice=${targetPrice}, preciseSol=${preciseSol}, actual SOL=${result.real_lp_sol_amount}`);
283
272
  result.force_close_num = counti;
284
273
  } catch (error) {
285
274
  throw new Error(`流动性计算错误:跳过订单后精确SOL计算失败 Liquidity calculation error: Precise SOL calculation failed after skipping order - ${error.message}`);
@@ -294,7 +283,7 @@ function calcLiqTokenBuy(price, buyTokenAmount, orders, onceMaxOrder, passOrder
294
283
  throw new Error(`流动性计算错误:无法处理跳过订单 ${i} 的流动性 Liquidity calculation error: Cannot process skipped order ${i} liquidity - ${error.message}`);
295
284
  }
296
285
  } else {
297
- // 累加锁定的流动性(正常情况)
286
+ // Accumulate locked liquidity (normal case)
298
287
  try {
299
288
  if (order.lock_lp_sol_amount === undefined || order.lock_lp_sol_amount === null) {
300
289
  throw new Error(`订单数据格式错误:订单 ${i} 缺少 lock_lp_sol_amount Order data format error: Order ${i} missing lock_lp_sol_amount`);
@@ -320,7 +309,7 @@ function calcLiqTokenBuy(price, buyTokenAmount, orders, onceMaxOrder, passOrder
320
309
 
321
310
  }
322
311
 
323
- // 如果遍历的订单数小于等于onceMaxOrder,说明链表结束,需要计算无限流动性
312
+ // If the number of traversed orders is less than or equal to onceMaxOrder, the chain has ended and infinite liquidity needs to be calculated
324
313
  if (orders.length <= onceMaxOrder && orders.length > 0) {
325
314
 
326
315
  const lastOrder = orders[orders.length - 1];
@@ -358,16 +347,16 @@ function calcLiqTokenBuy(price, buyTokenAmount, orders, onceMaxOrder, passOrder
358
347
  throw new Error(`流动性计算错误:无法转换无限流动性数值 Liquidity calculation error: Cannot convert infinite liquidity values - ${error.message}`);
359
348
  }
360
349
 
361
- // 进入无限流动性后 也要 , 计算实际使用的SOL数量 到能买到为止
350
+ // After entering infinite liquidity, also calculate the actual amount of SOL used, until enough can be bought
362
351
  if (result.real_lp_sol_amount === 0n) {
363
352
  if (result.free_lp_token_amount_sum > buyTokenAmountBigInt) {
364
- // 这时间隙流动性已经够买入的了
365
- // 计算最后精确需要买多少token
353
+ // At this point the gap liquidity is already enough to buy
354
+ // Calculate the final precise amount of token to buy
366
355
  try {
367
356
  const actualBuyAmount = buyTokenAmountBigInt - (result.free_lp_token_amount_sum - BigInt(tokenAmount));
368
357
  const [, preciseSol] = CurveAMM.buyFromPriceWithTokenOutput(lastEndPrice, actualBuyAmount)
369
358
  result.real_lp_sol_amount += BigInt(preciseSol);
370
- result.force_close_num = counti; // 强平订单数量
359
+ result.force_close_num = counti; // Number of force closed orders
371
360
  } catch (error) {
372
361
  throw new Error(`流动性计算错误:无限流动性精确SOL计算失败 Liquidity calculation error: Infinite liquidity precise SOL calculation failed - ${error.message}`);
373
362
  }
@@ -394,74 +383,63 @@ function calcLiqTokenBuy(price, buyTokenAmount, orders, onceMaxOrder, passOrder
394
383
 
395
384
 
396
385
  /**
397
- * 计算代币卖出时的流动性影响 Calculate liquidity impact for token sell operations
398
- *
399
- * 此函数分析卖出操作对价格区间内流动性的影响,计算可用的自由流动性、锁定流动性,
400
- * 并支持跳过指定订单(将其流动性视为可用)。适用于做空订单(down_orders)场景。
386
+ * Calculate liquidity impact for token sell operations
387
+ *
401
388
  * This function analyzes the liquidity impact of sell operations within price ranges,
402
389
  * calculates available free liquidity, locked liquidity, and supports skipping specific
403
390
  * orders (treating their liquidity as available). Applicable for short orders (down_orders) scenarios.
404
- *
405
- * @param {bigint|string|number} price - 当前代币价格,作为计算起始价格 Current token price, used as calculation start price
406
- * @param {bigint|string|number} sellTokenAmount - 卖出的代币数量,目标卖出数量 Amount of tokens to sell, target sell amount
407
- * @param {Array<Object>} orders - 订单数组,按 lock_lp_start_price 从大到小排序 Array of orders sorted by lock_lp_start_price (descending):
408
- * - order_type: {number} 订单类型(1=做多,2=做空) Order type (1=long, 2=short)
409
- * - mint: {string} 代币地址 Token mint address
410
- * - user: {string} 用户地址 User address
411
- * - lock_lp_start_price: {string} LP锁定开始价格(高价) LP lock start price (high price) (required)
412
- * - lock_lp_end_price: {string} LP锁定结束价格(低价) LP lock end price (low price) (required)
413
- * - lock_lp_sol_amount: {number} 锁定的SOL数量 Locked SOL amount (required)
414
- * - lock_lp_token_amount: {number} 锁定的代币数量 Locked token amount (required)
415
- * - start_time: {number} 开始时间戳 Start timestamp
416
- * - end_time: {number} 结束时间戳 End timestamp
417
- * - margin_sol_amount: {number} 保证金SOL数量 Margin SOL amount
418
- * - borrow_amount: {number} 借贷数量 Borrow amount
419
- * - position_asset_amount: {number} 持仓资产数量 Position asset amount
420
- * - borrow_fee: {number} 借贷费用 Borrow fee
421
- * - order_pda: {string} 订单PDA地址 Order PDA address (required for passOrder matching)
422
- * @param {number} onceMaxOrder - 一次处理的最大订单数,限制遍历范围 Maximum orders to process at once, limits traversal range
423
- * @param {string|null} passOrder - 需要跳过的订单PDA地址字符串,当该值与订单的order_pda匹配时,跳过该订单并将其流动性计入自由流动性 Order PDA address string to skip, when this value matches an order's order_pda, skip that order and count its liquidity as free liquidity
424
- *
425
- * @returns {Object} 流动性计算结果对象,包含详细的流动性分析数据 Liquidity calculation result object with detailed liquidity analysis data:
426
- *
427
- * **自由流动性 Free Liquidity:**
428
- * - free_lp_sol_amount_sum: {bigint} 可用自由流动性SOL总量,表示卖出时能获得的SOL,包含:1)价格间隙流动性 2)跳过订单的流动性 3)无限流动性(如有)
429
- * Total available free liquidity SOL amount, represents SOL obtainable from selling, includes: 1) price gap liquidity 2) skipped order liquidity 3) infinite liquidity (if any)
430
- * - free_lp_token_amount_sum: {bigint} 可用自由流动性Token总量,表示在不强平任何订单情况下可卖出的最大代币数量
431
- * Total available free liquidity token amount, represents max tokens sellable without force closing any orders
432
- *
433
- * **锁定流动性 Locked Liquidity:**
434
- * - lock_lp_sol_amount_sum: {bigint} 被锁定的流动性SOL总量,不包括跳过的订单,这部分流动性不可直接使用
435
- * Total locked liquidity SOL amount, excludes skipped orders, this liquidity is not directly usable
436
- * - lock_lp_token_amount_sum: {bigint} 被锁定的流动性Token总量,不包括跳过的订单,对应于锁定的SOL流动性
437
- * Total locked liquidity token amount, excludes skipped orders, corresponds to locked SOL liquidity
438
- *
439
- * **流动性状态标识 Liquidity Status Indicators:**
440
- * - has_infinite_lp: {boolean} 是否包含无限流动性,true表示订单链表已结束且计算了到最小价格(MIN_U128_PRICE)的流动性
441
- * Whether includes infinite liquidity, true means order chain ended and liquidity to min price (MIN_U128_PRICE) was calculated
442
- * - pass_order_id: {number} 被跳过的订单在数组中的索引位置,-1表示没有跳过任何订单,>=0表示跳过了对应索引的订单
443
- * Index of skipped order in array, -1 means no order skipped, >=0 means order at that index was skipped
444
- *
445
- * **卖出执行信息 Sell Execution Info:**
446
- * - force_close_num: {number} 需要强平的订单数量,表示为了卖出目标数量需要强制平仓多少个订单,0表示无需强平
447
- * Number of orders that need to be force closed, indicates how many orders need force closure to sell target amount, 0 means no force closure needed
448
- * - ideal_lp_sol_amount: {bigint} 理想SOL获得量,基于当前价格使用CurveAMM直接计算的理论最大SOL收益,不考虑流动性分布
449
- * Ideal SOL amount obtainable, theoretical maximum SOL revenue calculated directly from current price using CurveAMM, ignores liquidity distribution
450
- * - real_lp_sol_amount: {bigint} 实际SOL获得量,考虑真实流动性分布的精确SOL收益。0表示当前自由流动性不足以满足卖出需求,需要强平更多订单
451
- * Actual SOL amount obtainable, precise SOL revenue considering real liquidity distribution. 0 means current free liquidity insufficient for sell requirement, need to force close more orders
452
- *
453
- * @throws {Error} 参数验证错误:price、sellTokenAmount、orders、onceMaxOrder 参数无效 Parameter validation error: invalid price, sellTokenAmount, orders, or onceMaxOrder
454
- * @throws {Error} 价格转换错误:无法将价格参数转换为 BigInt Price conversion error: cannot convert price parameters to BigInt
455
- * @throws {Error} 流动性计算错误:CurveAMM 计算失败或数值转换错误 Liquidity calculation error: CurveAMM calculation failure or value conversion error
456
- * @throws {Error} 间隙流动性计算失败:价格间隙流动性计算异常 Gap liquidity calculation failure: price gap liquidity calculation exception
457
- * @throws {Error} 无限流动性计算失败:最小价格流动性计算异常 Infinite liquidity calculation failure: min price liquidity calculation exception
458
- * @throws {Error} 订单数据格式错误:订单对象缺少必需字段 Order data format error: order object missing required fields
391
+ *
392
+ * @param {bigint|string|number} price - Current token price, used as calculation start price
393
+ * @param {bigint|string|number} sellTokenAmount - Amount of tokens to sell, target sell amount
394
+ * @param {Array<Object>} orders - Array of orders sorted by lock_lp_start_price (descending):
395
+ * - order_type: {number} Order type (1=long, 2=short)
396
+ * - mint: {string} Token mint address
397
+ * - user: {string} User address
398
+ * - lock_lp_start_price: {string} LP lock start price (high price) (required)
399
+ * - lock_lp_end_price: {string} LP lock end price (low price) (required)
400
+ * - lock_lp_sol_amount: {number} Locked SOL amount (required)
401
+ * - lock_lp_token_amount: {number} Locked token amount (required)
402
+ * - start_time: {number} Start timestamp
403
+ * - end_time: {number} End timestamp
404
+ * - margin_sol_amount: {number} Margin SOL amount
405
+ * - borrow_amount: {number} Borrow amount
406
+ * - position_asset_amount: {number} Position asset amount
407
+ * - borrow_fee: {number} Borrow fee
408
+ * - order_pda: {string} Order PDA address (required for passOrder matching)
409
+ * @param {number} onceMaxOrder - Maximum orders to process at once, limits traversal range
410
+ * @param {string|null} passOrder - Order PDA address string to skip, when this value matches an order's order_pda, skip that order and count its liquidity as free liquidity
411
+ *
412
+ * @returns {Object} Liquidity calculation result object with detailed liquidity analysis data:
413
+ *
414
+ * **Free Liquidity:**
415
+ * - free_lp_sol_amount_sum: {bigint} Total available free liquidity SOL amount, represents SOL obtainable from selling, includes: 1) price gap liquidity 2) skipped order liquidity 3) infinite liquidity (if any)
416
+ * - free_lp_token_amount_sum: {bigint} Total available free liquidity token amount, represents max tokens sellable without force closing any orders
417
+ *
418
+ * **Locked Liquidity:**
419
+ * - lock_lp_sol_amount_sum: {bigint} Total locked liquidity SOL amount, excludes skipped orders, this liquidity is not directly usable
420
+ * - lock_lp_token_amount_sum: {bigint} Total locked liquidity token amount, excludes skipped orders, corresponds to locked SOL liquidity
421
+ *
422
+ * **Liquidity Status Indicators:**
423
+ * - has_infinite_lp: {boolean} Whether includes infinite liquidity, true means order chain ended and liquidity to min price (MIN_U128_PRICE) was calculated
424
+ * - pass_order_id: {number} Index of skipped order in array, -1 means no order skipped, >=0 means order at that index was skipped
425
+ *
426
+ * **Sell Execution Info:**
427
+ * - force_close_num: {number} Number of orders that need to be force closed, indicates how many orders need force closure to sell target amount, 0 means no force closure needed
428
+ * - ideal_lp_sol_amount: {bigint} Ideal SOL amount obtainable, theoretical maximum SOL revenue calculated directly from current price using CurveAMM, ignores liquidity distribution
429
+ * - real_lp_sol_amount: {bigint} Actual SOL amount obtainable, precise SOL revenue considering real liquidity distribution. 0 means current free liquidity insufficient for sell requirement, need to force close more orders
430
+ *
431
+ * @throws {Error} Parameter validation error: invalid price, sellTokenAmount, orders, or onceMaxOrder
432
+ * @throws {Error} Price conversion error: cannot convert price parameters to BigInt
433
+ * @throws {Error} Liquidity calculation error: CurveAMM calculation failure or value conversion error
434
+ * @throws {Error} Gap liquidity calculation failure: price gap liquidity calculation exception
435
+ * @throws {Error} Infinite liquidity calculation failure: min price liquidity calculation exception
436
+ * @throws {Error} Order data format error: order object missing required fields
459
437
  */
460
438
  function calcLiqTokenSell(price, sellTokenAmount, orders, onceMaxOrder, passOrder = null, initialVirtualSol = null, initialVirtualToken = null) {
461
- // 由于是卖出操作 肯定拿的是 down_orders 方向的 订单 lock_lp_start_price > lock_lp_end_price
462
- // 并且 lock_lp_start_price 在 orders 中是从大到小排序的
439
+ // Since this is a sell operation, the orders are definitely in the down_orders direction lock_lp_start_price > lock_lp_end_price
440
+ // And lock_lp_start_price is sorted in descending order in orders
463
441
 
464
- // 参数验证
442
+ // Parameter validation
465
443
  if (!price && price !== 0) {
466
444
  throw new Error('参数验证错误:price 参数不能为空 Parameter validation error: price cannot be null');
467
445
  }
@@ -479,15 +457,15 @@ function calcLiqTokenSell(price, sellTokenAmount, orders, onceMaxOrder, passOrde
479
457
  }
480
458
 
481
459
  const result = {
482
- free_lp_sol_amount_sum: 0n, // 间隙中可使用的sol流动性数量
483
- free_lp_token_amount_sum: 0n, // 间隙中可使用的token流动性数量
460
+ free_lp_sol_amount_sum: 0n, // Amount of SOL liquidity usable in the gaps
461
+ free_lp_token_amount_sum: 0n, // Amount of token liquidity usable in the gaps
484
462
  lock_lp_sol_amount_sum: 0n,
485
463
  lock_lp_token_amount_sum: 0n,
486
- has_infinite_lp: false, // 是否包含无限流动性
487
- pass_order_id: -1, // 跳过的订单索引
488
- force_close_num: 0, // 强平订单数量
489
- ideal_lp_sol_amount: 0n, // 理想情况下卖出sellTokenAmount能获得的SOL数量
490
- real_lp_sol_amount: 0n, // 实际卖出sellTokenAmount能获得的SOL数量
464
+ has_infinite_lp: false, // Whether includes infinite liquidity
465
+ pass_order_id: -1, // Index of skipped order
466
+ force_close_num: 0, // Number of force closed orders
467
+ ideal_lp_sol_amount: 0n, // Amount of SOL obtainable from selling sellTokenAmount under ideal conditions
468
+ real_lp_sol_amount: 0n, // Amount of SOL actually obtainable from selling sellTokenAmount
491
469
  }
492
470
 
493
471
  let sellTokenAmountBigInt;
@@ -497,10 +475,10 @@ function calcLiqTokenSell(price, sellTokenAmount, orders, onceMaxOrder, passOrde
497
475
  throw new Error(`价格转换错误:无法将 sellTokenAmount 转换为 BigInt Price conversion error: Cannot convert sellTokenAmount to BigInt - ${error.message}`);
498
476
  }
499
477
 
500
- // 声明用于跟踪前一次自由流动性总量的变量
478
+ // Declare variable for tracking the previous free liquidity total
501
479
  let prev_free_lp_sol_amount_sum;
502
480
 
503
- // 计算理想情况下卖出能获得的SOL数量
481
+ // Calculate the amount of SOL obtainable from selling under ideal conditions
504
482
  try {
505
483
  const priceBigInt = BigInt(price);
506
484
  const initialVirtualSolDecimal = new Decimal(initialVirtualSol).div(CurveAMM.SOL_PRECISION_FACTOR_DECIMAL);
@@ -513,12 +491,12 @@ function calcLiqTokenSell(price, sellTokenAmount, orders, onceMaxOrder, passOrde
513
491
  initialVirtualSolDecimal,
514
492
  initialVirtualTokenDecimal
515
493
  );
516
- // console.log(`理想计算: 当前价格=${priceBigInt}, 卖出代币=${sellTokenAmountBigInt}, 理想SOL=${result.ideal_lp_sol_amount}`);
494
+ // console.log(`ideal calculation: current price=${priceBigInt}, sell token=${sellTokenAmountBigInt}, ideal SOL=${result.ideal_lp_sol_amount}`);
517
495
  } catch (error) {
518
496
  throw new Error(`sell流动性计算错误:理想流动性计算失败 Liquidity calculation error: Ideal liquidity calculation failed - ${error.message}`);
519
497
  }
520
498
 
521
- // orders 长度为0 时要单独计算
499
+ // orders length of 0 requires separate calculation
522
500
  if (orders.length === 0) {
523
501
  const initialVirtualSolDecimal = new Decimal(initialVirtualSol).div(CurveAMM.SOL_PRECISION_FACTOR_DECIMAL);
524
502
  const initialVirtualTokenDecimal = new Decimal(initialVirtualToken).div(CurveAMM.TOKEN_PRECISION_FACTOR_DECIMAL);
@@ -531,7 +509,7 @@ function calcLiqTokenSell(price, sellTokenAmount, orders, onceMaxOrder, passOrde
531
509
  if (sellResult) {
532
510
  [result.free_lp_token_amount_sum, result.free_lp_sol_amount_sum] = sellResult;
533
511
  } else {
534
- // 如果当前价格已经低于最小价格,无法再卖出
512
+ // If the current price is already below the minimum price, no more can be sold
535
513
  result.free_lp_token_amount_sum = 0n;
536
514
  result.free_lp_sol_amount_sum = 0n;
537
515
  }
@@ -543,15 +521,15 @@ function calcLiqTokenSell(price, sellTokenAmount, orders, onceMaxOrder, passOrde
543
521
 
544
522
 
545
523
 
546
- // 选择较小值进行遍历
524
+ // Choose the smaller value for traversal
547
525
  const loopCount = Math.min(orders.length, onceMaxOrder);
548
526
 
549
527
  let counti = 0;
550
528
  for (let i = 0; i < loopCount; i++) {
551
529
  const order = orders[i];
552
- // console.log(`处理卖出订单[${i}]: 累计自由Token=${result.free_lp_token_amount_sum}, 目标=${sellTokenAmountBigInt}, 需要=${sellTokenAmountBigInt > result.free_lp_token_amount_sum}`);
530
+ // console.log(`processing sell order[${i}]: cumulative free Token=${result.free_lp_token_amount_sum}, target=${sellTokenAmountBigInt}, needed=${sellTokenAmountBigInt > result.free_lp_token_amount_sum}`);
553
531
 
554
- // 验证订单数据格式
532
+ // Validate order data format
555
533
  if (!order) {
556
534
  throw new Error(`订单数据格式错误:订单 ${i} 为空 Order data format error: Order ${i} is null`);
557
535
  }
@@ -563,15 +541,15 @@ function calcLiqTokenSell(price, sellTokenAmount, orders, onceMaxOrder, passOrde
563
541
  }
564
542
 
565
543
 
566
- // 计算间隙流动性(卖出方向:从高价到低价)
544
+ // Calculate gap liquidity (sell direction: from high price to low price)
567
545
  let startPrice, endPrice;
568
546
  try {
569
547
  if (i === 0) {
570
- // 第一个订单:从当前价格(高)到订单开始价格(低)的间隙
548
+ // First order: gap from current price (high) to order start price (low)
571
549
  startPrice = BigInt(price);
572
550
  endPrice = BigInt(order.lock_lp_start_price);
573
551
  } else {
574
- // 后续订单:从前一个订单结束价格(高)到当前订单开始价格(低)的间隙
552
+ // Subsequent orders: gap from previous order end price (high) to current order start price (low)
575
553
  startPrice = BigInt(orders[i - 1].lock_lp_end_price);
576
554
  endPrice = BigInt(order.lock_lp_start_price);
577
555
  }
@@ -580,7 +558,7 @@ function calcLiqTokenSell(price, sellTokenAmount, orders, onceMaxOrder, passOrde
580
558
  }
581
559
 
582
560
 
583
- // 如果存在价格间隙(卖出时startPrice应该大于endPrice)
561
+ // If a price gap exists (when selling, startPrice should be greater than endPrice)
584
562
  if (startPrice > endPrice) {
585
563
  try {
586
564
  const initialVirtualSolDecimal = new Decimal(initialVirtualSol).div(CurveAMM.SOL_PRECISION_FACTOR_DECIMAL);
@@ -595,25 +573,25 @@ function calcLiqTokenSell(price, sellTokenAmount, orders, onceMaxOrder, passOrde
595
573
  const [tokenAmount, solAmount] = gapLiquidity;
596
574
 
597
575
  try {
598
- prev_free_lp_sol_amount_sum = result.free_lp_sol_amount_sum; // 上次的值
576
+ prev_free_lp_sol_amount_sum = result.free_lp_sol_amount_sum; // Previous value
599
577
  result.free_lp_sol_amount_sum += BigInt(solAmount);
600
578
  result.free_lp_token_amount_sum += BigInt(tokenAmount);
601
- // console.log(`卖出间隙[${i}]: ${startPrice}→${endPrice}, 间隙Token=${tokenAmount}, 间隙SOL=${solAmount}, 累计自由Token=${result.free_lp_token_amount_sum}`);
579
+ // console.log(`sell gap[${i}]: ${startPrice}→${endPrice}, gap Token=${tokenAmount}, gap SOL=${solAmount}, cumulative free Token=${result.free_lp_token_amount_sum}`);
602
580
  } catch (error) {
603
581
  throw new Error(`流动性计算错误:无法转换间隙流动性数值 Liquidity calculation error: Cannot convert gap liquidity values - ${error.message}`);
604
582
  }
605
583
 
606
- // 计算实际获得的SOL数量 到能卖出为止
584
+ // Calculate the actual amount of SOL obtained, until enough can be sold
607
585
  if (result.real_lp_sol_amount === 0n) {
608
586
  if (result.free_lp_token_amount_sum >= sellTokenAmountBigInt) {
609
- // 这时间隙流动性已经够卖出的了
610
- // 计算精确能获得多少SOL
587
+ // At this point the gap liquidity is already enough to sell
588
+ // Calculate the precise amount of SOL obtainable
611
589
  try {
612
590
  const actualSellAmount = sellTokenAmountBigInt - (result.free_lp_token_amount_sum - BigInt(tokenAmount));
613
591
  const [, preciseSol] = CurveAMM.sellFromPriceWithTokenInput(startPrice, actualSellAmount);
614
592
  result.real_lp_sol_amount = prev_free_lp_sol_amount_sum + preciseSol;
615
- // console.log(`卖出实际计算[${i}]: 自由流动性已足够, actualSellAmount=${actualSellAmount}, preciseSol=${preciseSol}, 实际SOL=${result.real_lp_sol_amount}`);
616
- result.force_close_num = counti; // 强平订单数量
593
+ // console.log(`sell actual calculation[${i}]: free liquidity sufficient, actualSellAmount=${actualSellAmount}, preciseSol=${preciseSol}, actual SOL=${result.real_lp_sol_amount}`);
594
+ result.force_close_num = counti; // Number of force closed orders
617
595
  } catch (error) {
618
596
  throw new Error(`流动性计算错误:精确SOL计算失败 Liquidity calculation error: Precise SOL calculation failed - ${error.message}`);
619
597
  }
@@ -632,11 +610,11 @@ function calcLiqTokenSell(price, sellTokenAmount, orders, onceMaxOrder, passOrde
632
610
  } else {
633
611
  }
634
612
 
635
- // 检查是否需要跳过该订单(passOrder 逻辑)
613
+ // Check whether this order needs to be skipped (passOrder logic)
636
614
 
637
615
  if (passOrder == order.order_pda) {
638
616
 
639
- // 将跳过订单的流动性加到自由流动性中
617
+ // Add the skipped order's liquidity to the free liquidity
640
618
  try {
641
619
  if (order.lock_lp_sol_amount === undefined || order.lock_lp_sol_amount === null) {
642
620
  throw new Error(`订单数据格式错误:跳过订单 ${i} 缺少 lock_lp_sol_amount Order data format error: Skipped order ${i} missing lock_lp_sol_amount`);
@@ -645,19 +623,19 @@ function calcLiqTokenSell(price, sellTokenAmount, orders, onceMaxOrder, passOrde
645
623
  throw new Error(`订单数据格式错误:跳过订单 ${i} 缺少 lock_lp_token_amount Order data format error: Skipped order ${i} missing lock_lp_token_amount`);
646
624
  }
647
625
 
648
- const prevFreeSolSum = result.free_lp_sol_amount_sum; // 保存之前的值用于计算
626
+ const prevFreeSolSum = result.free_lp_sol_amount_sum; // Save the previous value for calculation
649
627
  result.free_lp_sol_amount_sum += BigInt(order.lock_lp_sol_amount);
650
628
  result.free_lp_token_amount_sum += BigInt(order.lock_lp_token_amount);
651
629
 
652
630
  result.pass_order_id = i;
653
631
 
654
632
 
655
- // 检查跳过订单后的自由流动性是否已满足卖出需求
633
+ // Check whether the free liquidity after skipping the order already meets the sell requirement
656
634
  if (result.real_lp_sol_amount === 0n) {
657
635
  if (result.free_lp_token_amount_sum >= sellTokenAmountBigInt) {
658
- // 自由流动性已经够卖出需求了
636
+ // Free liquidity is already enough for the sell requirement
659
637
  try {
660
- // 计算精确能获得多少SOL
638
+ // Calculate the precise amount of SOL obtainable
661
639
  const targetPrice = i === 0 ? BigInt(price) : BigInt(orders[i - 1].lock_lp_end_price);
662
640
  const actualSellAmount = sellTokenAmountBigInt - (result.free_lp_token_amount_sum - BigInt(order.lock_lp_token_amount));
663
641
  const [, preciseSol] = CurveAMM.sellFromPriceWithTokenInput(targetPrice, actualSellAmount);
@@ -676,7 +654,7 @@ function calcLiqTokenSell(price, sellTokenAmount, orders, onceMaxOrder, passOrde
676
654
  throw new Error(`流动性计算错误:无法处理跳过订单 ${i} 的流动性 Liquidity calculation error: Cannot process skipped order ${i} liquidity - ${error.message}`);
677
655
  }
678
656
  } else {
679
- // 累加锁定的流动性(正常情况)
657
+ // Accumulate locked liquidity (normal case)
680
658
  try {
681
659
  if (order.lock_lp_sol_amount === undefined || order.lock_lp_sol_amount === null) {
682
660
  throw new Error(`订单数据格式错误:订单 ${i} 缺少 lock_lp_sol_amount Order data format error: Order ${i} missing lock_lp_sol_amount`);
@@ -699,7 +677,7 @@ function calcLiqTokenSell(price, sellTokenAmount, orders, onceMaxOrder, passOrde
699
677
 
700
678
  }
701
679
 
702
- // 如果遍历的订单数小于等于onceMaxOrder,说明链表结束,需要计算无限流动性
680
+ // If the number of traversed orders is less than or equal to onceMaxOrder, the chain has ended and infinite liquidity needs to be calculated
703
681
  if (orders.length <= onceMaxOrder && orders.length > 0) {
704
682
 
705
683
  const lastOrder = orders[orders.length - 1];
@@ -740,15 +718,15 @@ function calcLiqTokenSell(price, sellTokenAmount, orders, onceMaxOrder, passOrde
740
718
  throw new Error(`流动性计算错误:无法转换无限流动性数值 Liquidity calculation error: Cannot convert infinite liquidity values - ${error.message}`);
741
719
  }
742
720
 
743
- // 进入无限流动性后,计算实际获得的SOL数量
721
+ // After entering infinite liquidity, calculate the actual amount of SOL obtained
744
722
  if (result.real_lp_sol_amount === 0n) {
745
723
  if (result.free_lp_token_amount_sum >= sellTokenAmountBigInt) {
746
- // 无限流动性够卖出需求了
724
+ // Infinite liquidity is enough for the sell requirement
747
725
  try {
748
726
  const actualSellAmount = sellTokenAmountBigInt - (result.free_lp_token_amount_sum - BigInt(tokenAmount));
749
727
  const [, preciseSol] = CurveAMM.sellFromPriceWithTokenInput(lastEndPrice, actualSellAmount);
750
728
  result.real_lp_sol_amount = prevFreeSolSum + preciseSol;
751
- result.force_close_num = counti; // 强平订单数量
729
+ result.force_close_num = counti; // Number of force closed orders
752
730
  } catch (error) {
753
731
  throw new Error(`流动性计算错误:无限流动性精确SOL计算失败 Liquidity calculation error: Infinite liquidity precise SOL calculation failed - ${error.message}`);
754
732
  }