pinpet-sdk 2.1.13 → 2.1.15
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.
- package/dist/pinpet-sdk.cjs.js +336 -61
- package/dist/pinpet-sdk.esm.js +336 -61
- package/dist/pinpet-sdk.js +336 -61
- package/dist/pinpet-sdk.js.map +1 -1
- package/package.json +1 -1
- package/src/idl/pinpet copy.json +3730 -0
- package/src/idl/pinpet.json +2 -2
- package/src/modules/simulator/buy_sell_token.js +15 -12
- package/src/modules/simulator/calc_sol_liq.js +257 -0
- package/src/modules/simulator.js +16 -1
- package/src/sdk.js +1 -1
- package/src/utils/constants.js +5 -5
package/dist/pinpet-sdk.js
CHANGED
|
@@ -30595,7 +30595,7 @@
|
|
|
30595
30595
|
* Implements constant product (xy=k) algorithm for automated market maker functionality
|
|
30596
30596
|
* Usage when importing: const CurveAMM = require("../tools/curve_amm");
|
|
30597
30597
|
*/
|
|
30598
|
-
class CurveAMM$
|
|
30598
|
+
class CurveAMM$8 {
|
|
30599
30599
|
/**
|
|
30600
30600
|
* Initial SOL reserve amount, represented as Decimal
|
|
30601
30601
|
* @type {Decimal}
|
|
@@ -31748,10 +31748,10 @@
|
|
|
31748
31748
|
}
|
|
31749
31749
|
}
|
|
31750
31750
|
|
|
31751
|
-
var curve_amm = CurveAMM$
|
|
31751
|
+
var curve_amm = CurveAMM$8;
|
|
31752
31752
|
|
|
31753
31753
|
const axios = axios_1;
|
|
31754
|
-
const CurveAMM$
|
|
31754
|
+
const CurveAMM$7 = curve_amm;
|
|
31755
31755
|
|
|
31756
31756
|
/**
|
|
31757
31757
|
* Fast API Module
|
|
@@ -32243,7 +32243,7 @@
|
|
|
32243
32243
|
|
|
32244
32244
|
if (!latestPrice) {
|
|
32245
32245
|
// If no price data, calculate initial price
|
|
32246
|
-
const initialPrice = CurveAMM$
|
|
32246
|
+
const initialPrice = CurveAMM$7.getInitialPrice();
|
|
32247
32247
|
if (initialPrice === null) {
|
|
32248
32248
|
throw new Error('price: 无法计算初始价格 Unable to calculate initial price');
|
|
32249
32249
|
}
|
|
@@ -33708,7 +33708,7 @@
|
|
|
33708
33708
|
|
|
33709
33709
|
var jsonBigintExports = jsonBigint.exports;
|
|
33710
33710
|
|
|
33711
|
-
const CurveAMM$
|
|
33711
|
+
const CurveAMM$6 = curve_amm;
|
|
33712
33712
|
const {transformOrdersData , checkPriceRangeOverlap} = stop_loss_utils;
|
|
33713
33713
|
const { PRICE_ADJUSTMENT_PERCENTAGE, MIN_STOP_LOSS_PERCENT } = utils$2;
|
|
33714
33714
|
jsonBigintExports({ storeAsString: false });
|
|
@@ -33866,12 +33866,12 @@
|
|
|
33866
33866
|
let currentPrice;
|
|
33867
33867
|
if (lastPrice === null || lastPrice === undefined || lastPrice === '0') {
|
|
33868
33868
|
console.log('Current price is empty, using initial price');
|
|
33869
|
-
currentPrice = CurveAMM$
|
|
33869
|
+
currentPrice = CurveAMM$6.getInitialPrice();
|
|
33870
33870
|
} else {
|
|
33871
33871
|
currentPrice = BigInt(lastPrice);
|
|
33872
33872
|
if (!currentPrice || currentPrice === 0n) {
|
|
33873
33873
|
console.log('Current price is 0, using initial price');
|
|
33874
|
-
currentPrice = CurveAMM$
|
|
33874
|
+
currentPrice = CurveAMM$6.getInitialPrice();
|
|
33875
33875
|
}
|
|
33876
33876
|
}
|
|
33877
33877
|
|
|
@@ -33916,7 +33916,7 @@
|
|
|
33916
33916
|
// console.log(` - buyTokenAmount: ${buyTokenAmount.toString()}`);
|
|
33917
33917
|
// console.log(` - Calling CurveAMM.sellFromPriceWithTokenInput...`);
|
|
33918
33918
|
|
|
33919
|
-
const tradeResult = CurveAMM$
|
|
33919
|
+
const tradeResult = CurveAMM$6.sellFromPriceWithTokenInput(stopLossStartPrice, buyTokenAmount);
|
|
33920
33920
|
|
|
33921
33921
|
//console.log(` - tradeResult:`, tradeResult);
|
|
33922
33922
|
|
|
@@ -33980,12 +33980,12 @@
|
|
|
33980
33980
|
let estimatedMargin = 0n;
|
|
33981
33981
|
try {
|
|
33982
33982
|
// 1. 计算从当前价格买入所需的SOL
|
|
33983
|
-
const buyResult = CurveAMM$
|
|
33983
|
+
const buyResult = CurveAMM$6.buyFromPriceWithTokenOutput(currentPrice, buyTokenAmount);
|
|
33984
33984
|
if (buyResult) {
|
|
33985
33985
|
const requiredSol = buyResult[1]; // SOL input amount
|
|
33986
33986
|
|
|
33987
33987
|
// 2. 计算平仓时扣除手续费后的收益
|
|
33988
|
-
const closeOutputSolAfterFee = CurveAMM$
|
|
33988
|
+
const closeOutputSolAfterFee = CurveAMM$6.calculateAmountAfterFee(finalTradeAmount, borrowFee);
|
|
33989
33989
|
|
|
33990
33990
|
// 3. 计算保证金 = 买入成本 - 平仓收益(扣费后)
|
|
33991
33991
|
if (closeOutputSolAfterFee !== null && requiredSol > closeOutputSolAfterFee) {
|
|
@@ -34175,12 +34175,12 @@
|
|
|
34175
34175
|
let currentPrice;
|
|
34176
34176
|
if (lastPrice === null || lastPrice === undefined || lastPrice === '0') {
|
|
34177
34177
|
console.log('Current price is empty, using initial price');
|
|
34178
|
-
currentPrice = CurveAMM$
|
|
34178
|
+
currentPrice = CurveAMM$6.getInitialPrice();
|
|
34179
34179
|
} else {
|
|
34180
34180
|
currentPrice = BigInt(lastPrice);
|
|
34181
34181
|
if (!currentPrice || currentPrice === 0n) {
|
|
34182
34182
|
console.log('Current price is 0, using initial price');
|
|
34183
|
-
currentPrice = CurveAMM$
|
|
34183
|
+
currentPrice = CurveAMM$6.getInitialPrice();
|
|
34184
34184
|
}
|
|
34185
34185
|
}
|
|
34186
34186
|
|
|
@@ -34223,7 +34223,7 @@
|
|
|
34223
34223
|
// console.log(` - sellTokenAmount: ${sellTokenAmount.toString()}`);
|
|
34224
34224
|
// console.log(` - Calling CurveAMM.buyFromPriceWithTokenOutput...`);
|
|
34225
34225
|
|
|
34226
|
-
const tradeResult = CurveAMM$
|
|
34226
|
+
const tradeResult = CurveAMM$6.buyFromPriceWithTokenOutput(stopLossStartPrice, sellTokenAmount);
|
|
34227
34227
|
|
|
34228
34228
|
//console.log(` - tradeResult:`, tradeResult);
|
|
34229
34229
|
|
|
@@ -34262,8 +34262,8 @@
|
|
|
34262
34262
|
//console.log(`调整后起始价格: ${stopLossStartPrice} / Adjusted start price: ${stopLossStartPrice}`);
|
|
34263
34263
|
|
|
34264
34264
|
// 安全检查:确保价格不会超过最大值 / Safety check: ensure price doesn't exceed maximum
|
|
34265
|
-
if (stopLossStartPrice >= CurveAMM$
|
|
34266
|
-
throw new Error(`Stop loss price exceeded maximum after adjustment: ${stopLossStartPrice} >= ${CurveAMM$
|
|
34265
|
+
if (stopLossStartPrice >= CurveAMM$6.MAX_U128_PRICE) {
|
|
34266
|
+
throw new Error(`Stop loss price exceeded maximum after adjustment: ${stopLossStartPrice} >= ${CurveAMM$6.MAX_U128_PRICE}`);
|
|
34267
34267
|
}
|
|
34268
34268
|
}
|
|
34269
34269
|
|
|
@@ -34286,7 +34286,7 @@
|
|
|
34286
34286
|
let estimatedMargin = 0n;
|
|
34287
34287
|
try {
|
|
34288
34288
|
// 1. 计算从当前价格卖出代币获得的SOL(开仓收益,不含手续费)
|
|
34289
|
-
const sellResult = CurveAMM$
|
|
34289
|
+
const sellResult = CurveAMM$6.sellFromPriceWithTokenInput(currentPrice, sellTokenAmount);
|
|
34290
34290
|
if (sellResult) {
|
|
34291
34291
|
const openingSolGain = sellResult[1]; // 卖出获得的SOL
|
|
34292
34292
|
|
|
@@ -34410,17 +34410,17 @@
|
|
|
34410
34410
|
|
|
34411
34411
|
// Calculate current price
|
|
34412
34412
|
if (lastPrice === null || lastPrice === undefined || lastPrice === '0') {
|
|
34413
|
-
currentPrice = CurveAMM$
|
|
34413
|
+
currentPrice = CurveAMM$6.getInitialPrice();
|
|
34414
34414
|
} else {
|
|
34415
34415
|
currentPrice = BigInt(lastPrice);
|
|
34416
34416
|
if (!currentPrice || currentPrice === 0n) {
|
|
34417
|
-
currentPrice = CurveAMM$
|
|
34417
|
+
currentPrice = CurveAMM$6.getInitialPrice();
|
|
34418
34418
|
}
|
|
34419
34419
|
}
|
|
34420
34420
|
|
|
34421
34421
|
// Calculate initial token amount from SOL amount using sellFromPriceWithSolOutput
|
|
34422
34422
|
// This gives us how many tokens we can get when we later sell for buySolAmount SOL
|
|
34423
|
-
const initialResult = CurveAMM$
|
|
34423
|
+
const initialResult = CurveAMM$6.sellFromPriceWithSolOutput(currentPrice, buySolAmount);
|
|
34424
34424
|
if (!initialResult) {
|
|
34425
34425
|
throw new Error('Failed to calculate token amount from SOL amount');
|
|
34426
34426
|
}
|
|
@@ -34577,17 +34577,17 @@
|
|
|
34577
34577
|
|
|
34578
34578
|
// Calculate current price
|
|
34579
34579
|
if (lastPrice === null || lastPrice === undefined || lastPrice === '0') {
|
|
34580
|
-
currentPrice = CurveAMM$
|
|
34580
|
+
currentPrice = CurveAMM$6.getInitialPrice();
|
|
34581
34581
|
} else {
|
|
34582
34582
|
currentPrice = BigInt(lastPrice);
|
|
34583
34583
|
if (!currentPrice || currentPrice === 0n) {
|
|
34584
|
-
currentPrice = CurveAMM$
|
|
34584
|
+
currentPrice = CurveAMM$6.getInitialPrice();
|
|
34585
34585
|
}
|
|
34586
34586
|
}
|
|
34587
34587
|
|
|
34588
34588
|
// Calculate initial token amount from SOL amount using buyFromPriceWithSolInput
|
|
34589
34589
|
// This gives us how many tokens we need to buy later using sellSolAmount SOL
|
|
34590
|
-
const initialResult = CurveAMM$
|
|
34590
|
+
const initialResult = CurveAMM$6.buyFromPriceWithSolInput(currentPrice, sellSolAmount);
|
|
34591
34591
|
if (!initialResult) {
|
|
34592
34592
|
throw new Error('Failed to calculate token amount from SOL amount');
|
|
34593
34593
|
}
|
|
@@ -34679,7 +34679,7 @@
|
|
|
34679
34679
|
simulateShortSolStopLoss: simulateShortSolStopLoss$1
|
|
34680
34680
|
};
|
|
34681
34681
|
|
|
34682
|
-
const CurveAMM$
|
|
34682
|
+
const CurveAMM$5 = curve_amm;
|
|
34683
34683
|
|
|
34684
34684
|
|
|
34685
34685
|
/**
|
|
@@ -34798,7 +34798,7 @@
|
|
|
34798
34798
|
const priceBigInt = BigInt(price);
|
|
34799
34799
|
const initialVirtualSolBigInt = BigInt(initialVirtualSol.toString());
|
|
34800
34800
|
const initialVirtualTokenBigInt = BigInt(initialVirtualToken.toString());
|
|
34801
|
-
[, result.ideal_lp_sol_amount] = CurveAMM$
|
|
34801
|
+
[, result.ideal_lp_sol_amount] = CurveAMM$5.buyFromPriceWithTokenOutputWithParams(
|
|
34802
34802
|
priceBigInt,
|
|
34803
34803
|
buyTokenAmountBigInt,
|
|
34804
34804
|
initialVirtualSolBigInt,
|
|
@@ -34812,7 +34812,7 @@
|
|
|
34812
34812
|
|
|
34813
34813
|
// orders 长度为0 时要单独计算
|
|
34814
34814
|
if (orders.length === 0) {
|
|
34815
|
-
[result.free_lp_sol_amount_sum, result.free_lp_token_amount_sum] = CurveAMM$
|
|
34815
|
+
[result.free_lp_sol_amount_sum, result.free_lp_token_amount_sum] = CurveAMM$5.buyFromPriceToPrice(BigInt(price), CurveAMM$5.MAX_U128_PRICE);
|
|
34816
34816
|
result.has_infinite_lp = true;
|
|
34817
34817
|
result.real_lp_sol_amount = result.ideal_lp_sol_amount;
|
|
34818
34818
|
return result
|
|
@@ -34860,7 +34860,7 @@
|
|
|
34860
34860
|
// 如果存在价格间隙,计算自由流动性
|
|
34861
34861
|
if (endPrice > startPrice) {
|
|
34862
34862
|
try {
|
|
34863
|
-
const gapLiquidity = CurveAMM$
|
|
34863
|
+
const gapLiquidity = CurveAMM$5.buyFromPriceToPrice(startPrice, endPrice);
|
|
34864
34864
|
if (gapLiquidity && Array.isArray(gapLiquidity) && gapLiquidity.length === 2) {
|
|
34865
34865
|
const [solAmount, tokenAmount] = gapLiquidity;
|
|
34866
34866
|
|
|
@@ -34882,7 +34882,7 @@
|
|
|
34882
34882
|
try {
|
|
34883
34883
|
const actualBuyAmount = buyTokenAmountBigInt - (result.free_lp_token_amount_sum - BigInt(tokenAmount));
|
|
34884
34884
|
// console.log("actualBuyAmount",actualBuyAmount)
|
|
34885
|
-
const [, preciseSol] = CurveAMM$
|
|
34885
|
+
const [, preciseSol] = CurveAMM$5.buyFromPriceWithTokenOutput(startPrice, actualBuyAmount);
|
|
34886
34886
|
result.real_lp_sol_amount = prev_free_lp_sol_amount_sum + BigInt(preciseSol);
|
|
34887
34887
|
|
|
34888
34888
|
// console.log(`实际计算[${i}]: 自由流动性已足够, actualBuyAmount=${actualBuyAmount}, preciseSol=${preciseSol}, 实际SOL=${result.real_lp_sol_amount}`);
|
|
@@ -34936,7 +34936,7 @@
|
|
|
34936
34936
|
// 从当前价格开始计算需要多少SOL来买到精确的token数量
|
|
34937
34937
|
const targetPrice = i === 0 ? BigInt(price) : BigInt(orders[i - 1].lock_lp_end_price);
|
|
34938
34938
|
const actualBuyAmount = buyTokenAmountBigInt - (result.free_lp_token_amount_sum - BigInt(order.lock_lp_token_amount));
|
|
34939
|
-
const [, preciseSol] = CurveAMM$
|
|
34939
|
+
const [, preciseSol] = CurveAMM$5.buyFromPriceWithTokenOutput(targetPrice, actualBuyAmount);
|
|
34940
34940
|
result.real_lp_sol_amount = prevFreeSolSum + BigInt(preciseSol);
|
|
34941
34941
|
// console.log(`实际计算[${i}]: 跳过订单后足够, targetPrice=${targetPrice}, preciseSol=${preciseSol}, 实际SOL=${result.real_lp_sol_amount}`);
|
|
34942
34942
|
result.force_close_num = counti;
|
|
@@ -34990,7 +34990,7 @@
|
|
|
34990
34990
|
let lastEndPrice, maxPrice;
|
|
34991
34991
|
try {
|
|
34992
34992
|
lastEndPrice = BigInt(lastOrder.lock_lp_end_price);
|
|
34993
|
-
maxPrice = CurveAMM$
|
|
34993
|
+
maxPrice = CurveAMM$5.MAX_U128_PRICE;
|
|
34994
34994
|
} catch (error) {
|
|
34995
34995
|
throw new Error(`价格转换错误:无法转换最后订单价格或最大价格 Price conversion error: Cannot convert last order price or max price - ${error.message}`);
|
|
34996
34996
|
}
|
|
@@ -34998,7 +34998,7 @@
|
|
|
34998
34998
|
|
|
34999
34999
|
if (maxPrice > lastEndPrice) {
|
|
35000
35000
|
try {
|
|
35001
|
-
const infiniteLiquidity = CurveAMM$
|
|
35001
|
+
const infiniteLiquidity = CurveAMM$5.buyFromPriceToPrice(lastEndPrice, maxPrice);
|
|
35002
35002
|
if (infiniteLiquidity && Array.isArray(infiniteLiquidity) && infiniteLiquidity.length === 2) {
|
|
35003
35003
|
const [solAmount, tokenAmount] = infiniteLiquidity;
|
|
35004
35004
|
|
|
@@ -35017,7 +35017,7 @@
|
|
|
35017
35017
|
// 计算最后精确需要买多少token
|
|
35018
35018
|
try {
|
|
35019
35019
|
const actualBuyAmount = buyTokenAmountBigInt - (result.free_lp_token_amount_sum - BigInt(tokenAmount));
|
|
35020
|
-
const [, preciseSol] = CurveAMM$
|
|
35020
|
+
const [, preciseSol] = CurveAMM$5.buyFromPriceWithTokenOutput(lastEndPrice, actualBuyAmount);
|
|
35021
35021
|
result.real_lp_sol_amount += BigInt(preciseSol);
|
|
35022
35022
|
result.force_close_num = counti; // 强平订单数量
|
|
35023
35023
|
} catch (error) {
|
|
@@ -35157,7 +35157,7 @@
|
|
|
35157
35157
|
const priceBigInt = BigInt(price);
|
|
35158
35158
|
const initialVirtualSolBigInt = BigInt(initialVirtualSol.toString());
|
|
35159
35159
|
const initialVirtualTokenBigInt = BigInt(initialVirtualToken.toString());
|
|
35160
|
-
[, result.ideal_lp_sol_amount] = CurveAMM$
|
|
35160
|
+
[, result.ideal_lp_sol_amount] = CurveAMM$5.sellFromPriceWithTokenInputWithParams(
|
|
35161
35161
|
priceBigInt,
|
|
35162
35162
|
sellTokenAmountBigInt,
|
|
35163
35163
|
initialVirtualSolBigInt,
|
|
@@ -35172,9 +35172,9 @@
|
|
|
35172
35172
|
if (orders.length === 0) {
|
|
35173
35173
|
const initialVirtualSolBigInt = BigInt(initialVirtualSol.toString());
|
|
35174
35174
|
const initialVirtualTokenBigInt = BigInt(initialVirtualToken.toString());
|
|
35175
|
-
const sellResult = CurveAMM$
|
|
35175
|
+
const sellResult = CurveAMM$5.sellFromPriceToPriceWithParams(
|
|
35176
35176
|
BigInt(price),
|
|
35177
|
-
CurveAMM$
|
|
35177
|
+
CurveAMM$5.MIN_U128_PRICE,
|
|
35178
35178
|
initialVirtualSolBigInt,
|
|
35179
35179
|
initialVirtualTokenBigInt
|
|
35180
35180
|
);
|
|
@@ -35233,7 +35233,7 @@
|
|
|
35233
35233
|
// 如果存在价格间隙(卖出时startPrice应该大于endPrice)
|
|
35234
35234
|
if (startPrice > endPrice) {
|
|
35235
35235
|
try {
|
|
35236
|
-
const gapLiquidity = CurveAMM$
|
|
35236
|
+
const gapLiquidity = CurveAMM$5.sellFromPriceToPrice(startPrice, endPrice);
|
|
35237
35237
|
if (gapLiquidity && Array.isArray(gapLiquidity) && gapLiquidity.length === 2) {
|
|
35238
35238
|
const [tokenAmount, solAmount] = gapLiquidity;
|
|
35239
35239
|
|
|
@@ -35253,7 +35253,7 @@
|
|
|
35253
35253
|
// 计算精确能获得多少SOL
|
|
35254
35254
|
try {
|
|
35255
35255
|
const actualSellAmount = sellTokenAmountBigInt - (result.free_lp_token_amount_sum - BigInt(tokenAmount));
|
|
35256
|
-
const [, preciseSol] = CurveAMM$
|
|
35256
|
+
const [, preciseSol] = CurveAMM$5.sellFromPriceWithTokenInput(startPrice, actualSellAmount);
|
|
35257
35257
|
result.real_lp_sol_amount = prev_free_lp_sol_amount_sum + preciseSol;
|
|
35258
35258
|
// console.log(`卖出实际计算[${i}]: 自由流动性已足够, actualSellAmount=${actualSellAmount}, preciseSol=${preciseSol}, 实际SOL=${result.real_lp_sol_amount}`);
|
|
35259
35259
|
result.force_close_num = counti; // 强平订单数量
|
|
@@ -35302,7 +35302,7 @@
|
|
|
35302
35302
|
// 计算精确能获得多少SOL
|
|
35303
35303
|
const targetPrice = i === 0 ? BigInt(price) : BigInt(orders[i - 1].lock_lp_end_price);
|
|
35304
35304
|
const actualSellAmount = sellTokenAmountBigInt - (result.free_lp_token_amount_sum - BigInt(order.lock_lp_token_amount));
|
|
35305
|
-
const [, preciseSol] = CurveAMM$
|
|
35305
|
+
const [, preciseSol] = CurveAMM$5.sellFromPriceWithTokenInput(targetPrice, actualSellAmount);
|
|
35306
35306
|
result.real_lp_sol_amount = prevFreeSolSum + preciseSol;
|
|
35307
35307
|
result.force_close_num = counti;
|
|
35308
35308
|
} catch (error) {
|
|
@@ -35352,7 +35352,7 @@
|
|
|
35352
35352
|
let lastEndPrice, minPrice;
|
|
35353
35353
|
try {
|
|
35354
35354
|
lastEndPrice = BigInt(lastOrder.lock_lp_end_price);
|
|
35355
|
-
minPrice = CurveAMM$
|
|
35355
|
+
minPrice = CurveAMM$5.MIN_U128_PRICE;
|
|
35356
35356
|
} catch (error) {
|
|
35357
35357
|
throw new Error(`价格转换错误:无法转换最后订单价格或最小价格 Price conversion error: Cannot convert last order price or min price - ${error.message}`);
|
|
35358
35358
|
}
|
|
@@ -35361,7 +35361,7 @@
|
|
|
35361
35361
|
if (lastEndPrice > minPrice) {
|
|
35362
35362
|
|
|
35363
35363
|
try {
|
|
35364
|
-
const infiniteLiquidity = CurveAMM$
|
|
35364
|
+
const infiniteLiquidity = CurveAMM$5.sellFromPriceToPrice(lastEndPrice, minPrice);
|
|
35365
35365
|
if (infiniteLiquidity && Array.isArray(infiniteLiquidity) && infiniteLiquidity.length === 2) {
|
|
35366
35366
|
const [tokenAmount, solAmount] = infiniteLiquidity;
|
|
35367
35367
|
|
|
@@ -35381,7 +35381,7 @@
|
|
|
35381
35381
|
// 无限流动性够卖出需求了
|
|
35382
35382
|
try {
|
|
35383
35383
|
const actualSellAmount = sellTokenAmountBigInt - (result.free_lp_token_amount_sum - BigInt(tokenAmount));
|
|
35384
|
-
const [, preciseSol] = CurveAMM$
|
|
35384
|
+
const [, preciseSol] = CurveAMM$5.sellFromPriceWithTokenInput(lastEndPrice, actualSellAmount);
|
|
35385
35385
|
result.real_lp_sol_amount = prevFreeSolSum + preciseSol;
|
|
35386
35386
|
result.force_close_num = counti; // 强平订单数量
|
|
35387
35387
|
} catch (error) {
|
|
@@ -35439,7 +35439,7 @@
|
|
|
35439
35439
|
async function simulateTokenBuy$1(mint, buyTokenAmount, passOrder = null, lastPrice = null, ordersData = null) {
|
|
35440
35440
|
// 获取价格和订单数据
|
|
35441
35441
|
|
|
35442
|
-
|
|
35442
|
+
console.log('simulateTokenBuy', mint, buyTokenAmount, passOrder, lastPrice, ordersData);
|
|
35443
35443
|
|
|
35444
35444
|
let price = lastPrice;
|
|
35445
35445
|
if (!price) {
|
|
@@ -35484,17 +35484,20 @@
|
|
|
35484
35484
|
curveData.initialVirtualToken
|
|
35485
35485
|
);
|
|
35486
35486
|
|
|
35487
|
-
|
|
35488
|
-
|
|
35489
|
-
|
|
35490
|
-
|
|
35491
|
-
|
|
35492
|
-
|
|
35493
|
-
|
|
35494
|
-
|
|
35495
|
-
|
|
35496
|
-
|
|
35497
|
-
|
|
35487
|
+
console.log("liqResult:",liqResult);
|
|
35488
|
+
|
|
35489
|
+
|
|
35490
|
+
console.log('\n=== calcLiqTokenBuy 返回结果 ===');
|
|
35491
|
+
console.log('自由流动性 SOL 总量:', liqResult.free_lp_sol_amount_sum.toString());
|
|
35492
|
+
console.log('自由流动性 Token 总量:', liqResult.free_lp_token_amount_sum.toString());
|
|
35493
|
+
console.log('锁定流动性 SOL 总量:', liqResult.lock_lp_sol_amount_sum.toString());
|
|
35494
|
+
console.log('锁定流动性 Token 总量:', liqResult.lock_lp_token_amount_sum.toString());
|
|
35495
|
+
console.log('是否包含无限流动性:', liqResult.has_infinite_lp);
|
|
35496
|
+
console.log('跳过的订单索引:', liqResult.pass_order_id);
|
|
35497
|
+
console.log('需要强平的订单数量:', liqResult.force_close_num);
|
|
35498
|
+
console.log('理想 SOL 使用量:', liqResult.ideal_lp_sol_amount.toString());
|
|
35499
|
+
console.log('实际 SOL 使用量:', liqResult.real_lp_sol_amount.toString());
|
|
35500
|
+
console.log('===============================\n');
|
|
35498
35501
|
|
|
35499
35502
|
// Convert to BigInt for calculations
|
|
35500
35503
|
const buyTokenAmountBig = BigInt(buyTokenAmount);
|
|
@@ -35950,11 +35953,268 @@
|
|
|
35950
35953
|
simulateShortClose: simulateShortClose$1
|
|
35951
35954
|
};
|
|
35952
35955
|
|
|
35956
|
+
const CurveAMM$4 = curve_amm;
|
|
35957
|
+
|
|
35958
|
+
/**
|
|
35959
|
+
* 计算使用指定SOL数量买入时能获得的Token数量
|
|
35960
|
+
* @param {bigint|string} price - 当前交易价格 (u128格式)
|
|
35961
|
+
* @param {bigint|string|number} buySolAmount - 需要花费的SOL数量 (lamports, 9位精度)
|
|
35962
|
+
* @param {Array} orders - 锁定流动性的订单数组
|
|
35963
|
+
* @param {number} onceMaxOrder - 单次循环最大订单数
|
|
35964
|
+
* @param {string|number|null} passOrderID - 需要跳过的订单ID(与order_id字段比较)
|
|
35965
|
+
* @param {string|number|Decimal|null} initialVirtualSol - 流动池SOL数量
|
|
35966
|
+
* @param {string|number|Decimal|null} initialVirtualToken - 流动池Token数量
|
|
35967
|
+
* @returns {Object} { tokenAmount: bigint, msg: string, closedOrdersCount: number }
|
|
35968
|
+
*/
|
|
35969
|
+
function calcLiqSolBuy$1(price, buySolAmount, orders, onceMaxOrder, passOrderID = null, initialVirtualSol = null, initialVirtualToken = null){
|
|
35970
|
+
|
|
35971
|
+
// 1. 参数验证
|
|
35972
|
+
// 转换为 bigint 以便比较
|
|
35973
|
+
let priceBigInt;
|
|
35974
|
+
let buySolAmountBigInt;
|
|
35975
|
+
|
|
35976
|
+
try {
|
|
35977
|
+
priceBigInt = typeof price === 'bigint' ? price : BigInt(price);
|
|
35978
|
+
buySolAmountBigInt = typeof buySolAmount === 'bigint' ? buySolAmount : BigInt(buySolAmount);
|
|
35979
|
+
} catch (error) {
|
|
35980
|
+
return {
|
|
35981
|
+
tokenAmount: 0n,
|
|
35982
|
+
msg: '参数格式错误:无法转换为bigint',
|
|
35983
|
+
closedOrdersCount: 0
|
|
35984
|
+
};
|
|
35985
|
+
}
|
|
35986
|
+
|
|
35987
|
+
// 检查价格和金额是否有效
|
|
35988
|
+
if (priceBigInt <= 0n) {
|
|
35989
|
+
return {
|
|
35990
|
+
tokenAmount: 0n,
|
|
35991
|
+
msg: '计算失败:价格必须大于0',
|
|
35992
|
+
closedOrdersCount: 0
|
|
35993
|
+
};
|
|
35994
|
+
}
|
|
35995
|
+
|
|
35996
|
+
if (buySolAmountBigInt <= 0n) {
|
|
35997
|
+
return {
|
|
35998
|
+
tokenAmount: 0n,
|
|
35999
|
+
msg: '计算失败:买入金额必须大于0',
|
|
36000
|
+
closedOrdersCount: 0
|
|
36001
|
+
};
|
|
36002
|
+
}
|
|
36003
|
+
|
|
36004
|
+
// 2. 设置默认流动池参数
|
|
36005
|
+
const virtualSol = initialVirtualSol !== null ? initialVirtualSol : CurveAMM$4.INITIAL_SOL_RESERVE_DECIMAL;
|
|
36006
|
+
const virtualToken = initialVirtualToken !== null ? initialVirtualToken : CurveAMM$4.INITIAL_TOKEN_RESERVE_DECIMAL;
|
|
36007
|
+
|
|
36008
|
+
// 3. 处理空订单情况(第一阶段)
|
|
36009
|
+
if (!orders || orders.length === 0) {
|
|
36010
|
+
// 直接计算完整流动性下的买入
|
|
36011
|
+
const result = CurveAMM$4.buyFromPriceWithSolInputWithParams(
|
|
36012
|
+
price,
|
|
36013
|
+
buySolAmount,
|
|
36014
|
+
virtualSol,
|
|
36015
|
+
virtualToken
|
|
36016
|
+
);
|
|
36017
|
+
|
|
36018
|
+
if (result === null) {
|
|
36019
|
+
return {
|
|
36020
|
+
tokenAmount: 0n,
|
|
36021
|
+
msg: '计算失败:价格或参数无效',
|
|
36022
|
+
closedOrdersCount: 0
|
|
36023
|
+
};
|
|
36024
|
+
}
|
|
36025
|
+
|
|
36026
|
+
const [endPrice, tokenAmount] = result;
|
|
36027
|
+
return {
|
|
36028
|
+
tokenAmount: tokenAmount,
|
|
36029
|
+
msg: '流动性完整,无锁定订单',
|
|
36030
|
+
closedOrdersCount: 0
|
|
36031
|
+
};
|
|
36032
|
+
}
|
|
36033
|
+
|
|
36034
|
+
// 4. 处理有订单的情况(第二阶段:分段流动性计算)
|
|
36035
|
+
|
|
36036
|
+
// 初始化变量
|
|
36037
|
+
let currentPrice = priceBigInt; // 当前价格指针
|
|
36038
|
+
let remainingSol = buySolAmountBigInt; // 剩余可用 SOL
|
|
36039
|
+
let totalTokenAmount = 0n; // 累计获得的 token
|
|
36040
|
+
let closedOrdersCount = 0; // 平仓订单数量
|
|
36041
|
+
let processedOrders = 0; // 已处理订单数
|
|
36042
|
+
|
|
36043
|
+
// 检查当前价格是否高于第一个订单的结束价格
|
|
36044
|
+
if (orders.length > 0) {
|
|
36045
|
+
const firstOrderEndPrice = typeof orders[0].lock_lp_end_price === 'bigint'
|
|
36046
|
+
? orders[0].lock_lp_end_price
|
|
36047
|
+
: BigInt(orders[0].lock_lp_end_price);
|
|
36048
|
+
|
|
36049
|
+
if (currentPrice >= firstOrderEndPrice) {
|
|
36050
|
+
return {
|
|
36051
|
+
tokenAmount: 0n,
|
|
36052
|
+
msg: '错误:当前价格已高于第一个订单的结束价格',
|
|
36053
|
+
closedOrdersCount: 0
|
|
36054
|
+
};
|
|
36055
|
+
}
|
|
36056
|
+
}
|
|
36057
|
+
|
|
36058
|
+
// 遍历订单(最多 onceMaxOrder 个)
|
|
36059
|
+
for (let i = 0; i < orders.length && processedOrders < onceMaxOrder; i++) {
|
|
36060
|
+
const order = orders[i];
|
|
36061
|
+
|
|
36062
|
+
// 检查是否需要跳过此订单
|
|
36063
|
+
if (passOrderID !== null && order.order_id !== undefined) {
|
|
36064
|
+
// 将两者都转换为字符串进行比较
|
|
36065
|
+
const orderIdStr = String(order.order_id);
|
|
36066
|
+
const passOrderIdStr = String(passOrderID);
|
|
36067
|
+
|
|
36068
|
+
if (orderIdStr === passOrderIdStr) {
|
|
36069
|
+
// 跳过此订单,不处理其锁定区间,继续下一个订单
|
|
36070
|
+
continue;
|
|
36071
|
+
}
|
|
36072
|
+
}
|
|
36073
|
+
|
|
36074
|
+
// 转换订单价格为 bigint
|
|
36075
|
+
let lockStartPrice, lockEndPrice;
|
|
36076
|
+
try {
|
|
36077
|
+
lockStartPrice = typeof order.lock_lp_start_price === 'bigint'
|
|
36078
|
+
? order.lock_lp_start_price
|
|
36079
|
+
: BigInt(order.lock_lp_start_price);
|
|
36080
|
+
lockEndPrice = typeof order.lock_lp_end_price === 'bigint'
|
|
36081
|
+
? order.lock_lp_end_price
|
|
36082
|
+
: BigInt(order.lock_lp_end_price);
|
|
36083
|
+
} catch (error) {
|
|
36084
|
+
return {
|
|
36085
|
+
tokenAmount: 0n,
|
|
36086
|
+
msg: `错误:订单${i}的价格格式无效`,
|
|
36087
|
+
closedOrdersCount: closedOrdersCount
|
|
36088
|
+
};
|
|
36089
|
+
}
|
|
36090
|
+
|
|
36091
|
+
// 步骤1:计算可用区间(currentPrice → lockStartPrice)
|
|
36092
|
+
if (currentPrice < lockStartPrice) {
|
|
36093
|
+
// 1.1 计算这段区间需要多少 SOL 和能获得多少 token
|
|
36094
|
+
const result = CurveAMM$4.buyFromPriceToPriceWithParams(
|
|
36095
|
+
currentPrice,
|
|
36096
|
+
lockStartPrice,
|
|
36097
|
+
virtualSol,
|
|
36098
|
+
virtualToken
|
|
36099
|
+
);
|
|
36100
|
+
|
|
36101
|
+
// 检查计算是否成功
|
|
36102
|
+
if (result === null) {
|
|
36103
|
+
return {
|
|
36104
|
+
tokenAmount: 0n,
|
|
36105
|
+
msg: `错误:计算价格区间失败(订单${i})`,
|
|
36106
|
+
closedOrdersCount: closedOrdersCount
|
|
36107
|
+
};
|
|
36108
|
+
}
|
|
36109
|
+
|
|
36110
|
+
const [solNeeded, tokenGained] = result;
|
|
36111
|
+
|
|
36112
|
+
// 1.2 判断剩余 SOL 是否足够
|
|
36113
|
+
if (remainingSol >= solNeeded) {
|
|
36114
|
+
// 足够:买完这段区间,继续下一段
|
|
36115
|
+
remainingSol -= solNeeded;
|
|
36116
|
+
totalTokenAmount += tokenGained;
|
|
36117
|
+
currentPrice = lockStartPrice;
|
|
36118
|
+
} else {
|
|
36119
|
+
// 不够:用完剩余 SOL,计算能买多少,然后返回
|
|
36120
|
+
const finalResult = CurveAMM$4.buyFromPriceWithSolInputWithParams(
|
|
36121
|
+
currentPrice,
|
|
36122
|
+
remainingSol,
|
|
36123
|
+
virtualSol,
|
|
36124
|
+
virtualToken
|
|
36125
|
+
);
|
|
36126
|
+
|
|
36127
|
+
if (finalResult === null) {
|
|
36128
|
+
return {
|
|
36129
|
+
tokenAmount: 0n,
|
|
36130
|
+
msg: '错误:计算最终买入失败',
|
|
36131
|
+
closedOrdersCount: closedOrdersCount
|
|
36132
|
+
};
|
|
36133
|
+
}
|
|
36134
|
+
|
|
36135
|
+
const [finalPrice, finalTokenGained] = finalResult;
|
|
36136
|
+
totalTokenAmount += finalTokenGained;
|
|
36137
|
+
|
|
36138
|
+
return {
|
|
36139
|
+
tokenAmount: totalTokenAmount,
|
|
36140
|
+
msg: `SOL用完,最终价格: ${finalPrice.toString()}`,
|
|
36141
|
+
closedOrdersCount: closedOrdersCount
|
|
36142
|
+
};
|
|
36143
|
+
}
|
|
36144
|
+
}
|
|
36145
|
+
|
|
36146
|
+
// 步骤2:跳过锁定区间(lockStartPrice → lockEndPrice)
|
|
36147
|
+
currentPrice = lockEndPrice;
|
|
36148
|
+
processedOrders++;
|
|
36149
|
+
|
|
36150
|
+
// 步骤3:判断是否平仓
|
|
36151
|
+
// 如果价格到达 lockEndPrice,说明这个订单被平仓
|
|
36152
|
+
closedOrdersCount++;
|
|
36153
|
+
|
|
36154
|
+
// 检查 SOL 是否已用完
|
|
36155
|
+
if (remainingSol === 0n) {
|
|
36156
|
+
return {
|
|
36157
|
+
tokenAmount: totalTokenAmount,
|
|
36158
|
+
msg: `SOL刚好用完,最终价格: ${currentPrice.toString()}`,
|
|
36159
|
+
closedOrdersCount: closedOrdersCount
|
|
36160
|
+
};
|
|
36161
|
+
}
|
|
36162
|
+
}
|
|
36163
|
+
|
|
36164
|
+
// 步骤4:处理最后的无限流动性区间
|
|
36165
|
+
// 所有订单处理完后,用剩余 SOL 继续买入
|
|
36166
|
+
if (remainingSol > 0n) {
|
|
36167
|
+
const finalResult = CurveAMM$4.buyFromPriceWithSolInputWithParams(
|
|
36168
|
+
currentPrice,
|
|
36169
|
+
remainingSol,
|
|
36170
|
+
virtualSol,
|
|
36171
|
+
virtualToken
|
|
36172
|
+
);
|
|
36173
|
+
|
|
36174
|
+
if (finalResult === null) {
|
|
36175
|
+
return {
|
|
36176
|
+
tokenAmount: 0n,
|
|
36177
|
+
msg: '错误:计算无限流动性区间失败',
|
|
36178
|
+
closedOrdersCount: closedOrdersCount
|
|
36179
|
+
};
|
|
36180
|
+
}
|
|
36181
|
+
|
|
36182
|
+
const [finalPrice, finalTokenGained] = finalResult;
|
|
36183
|
+
totalTokenAmount += finalTokenGained;
|
|
36184
|
+
|
|
36185
|
+
return {
|
|
36186
|
+
tokenAmount: totalTokenAmount,
|
|
36187
|
+
msg: `买入完成,最终价格: ${finalPrice.toString()}`,
|
|
36188
|
+
closedOrdersCount: closedOrdersCount
|
|
36189
|
+
};
|
|
36190
|
+
}
|
|
36191
|
+
|
|
36192
|
+
// 步骤5:SOL 刚好用完
|
|
36193
|
+
return {
|
|
36194
|
+
tokenAmount: totalTokenAmount,
|
|
36195
|
+
msg: `SOL刚好用完,最终价格: ${currentPrice.toString()}`,
|
|
36196
|
+
closedOrdersCount: closedOrdersCount
|
|
36197
|
+
};
|
|
36198
|
+
|
|
36199
|
+
}
|
|
36200
|
+
|
|
36201
|
+
|
|
36202
|
+
function calcLiqSolSell$1(price, sellSolAmount, orders, onceMaxOrder, passOrder = null, initialVirtualSol = null, initialVirtualToken = null) {
|
|
36203
|
+
|
|
36204
|
+
|
|
36205
|
+
}
|
|
36206
|
+
|
|
36207
|
+
|
|
36208
|
+
var calc_sol_liq = {
|
|
36209
|
+
calcLiqSolBuy: calcLiqSolBuy$1,
|
|
36210
|
+
calcLiqSolSell: calcLiqSolSell$1
|
|
36211
|
+
};
|
|
36212
|
+
|
|
35953
36213
|
const CurveAMM$3 = curve_amm;
|
|
35954
36214
|
const { simulateLongStopLoss, simulateShortStopLoss, simulateLongSolStopLoss, simulateShortSolStopLoss } = long_shrot_stop;
|
|
35955
36215
|
const { simulateTokenBuy, simulateTokenSell } = buy_sell_token;
|
|
35956
36216
|
const { simulateLongClose, simulateShortClose } = close_indices;
|
|
35957
|
-
|
|
36217
|
+
const {calcLiqSolBuy,calcLiqSolSell } = calc_sol_liq;
|
|
35958
36218
|
|
|
35959
36219
|
|
|
35960
36220
|
|
|
@@ -36160,6 +36420,12 @@
|
|
|
36160
36420
|
const priceResult = await this.sdk.data.price(mint);
|
|
36161
36421
|
const ordersResult = await this.sdk.data.orders(mint, { type: 'down_orders' });
|
|
36162
36422
|
|
|
36423
|
+
console.log("ordersResult:",ordersResult);
|
|
36424
|
+
|
|
36425
|
+
const upOrdersResult = await this.sdk.data.orders(mint, { type: 'up_orders' });
|
|
36426
|
+
console.log("upOrdersResult:",upOrdersResult);
|
|
36427
|
+
console.log("upOrdersResult:",upOrdersResult.data.orders);
|
|
36428
|
+
|
|
36163
36429
|
if (!priceResult || !ordersResult) {
|
|
36164
36430
|
return {
|
|
36165
36431
|
success: false,
|
|
@@ -36179,6 +36445,15 @@
|
|
|
36179
36445
|
const solInDecimal = Number(solAmountBigInt) / 1e9; // Convert lamports to SOL
|
|
36180
36446
|
const estimatedTokenAmount = BigInt(Math.floor((solInDecimal / priceDecimal) * 1e9)); // Convert to token lamports (9-digit precision)
|
|
36181
36447
|
|
|
36448
|
+
// Get curve account data for initialVirtualSol and initialVirtualToken
|
|
36449
|
+
const curveAccount = await this.sdk.chain.getCurveAccount(mint);
|
|
36450
|
+
const initialVirtualSol = curveAccount.initialVirtualSol;
|
|
36451
|
+
const initialVirtualToken = curveAccount.initialVirtualToken;
|
|
36452
|
+
|
|
36453
|
+
const reSolBuy = calcLiqSolBuy(currentPrice, buySolAmount, upOrdersResult.data.orders, 50, null, initialVirtualSol, initialVirtualToken);
|
|
36454
|
+
|
|
36455
|
+
|
|
36456
|
+
|
|
36182
36457
|
// Call simulateTokenBuy with estimated amount
|
|
36183
36458
|
const tokenBuyResult = await this.simulateTokenBuy(mint, estimatedTokenAmount, null, priceResult, ordersResult);
|
|
36184
36459
|
|
|
@@ -38001,7 +38276,7 @@
|
|
|
38001
38276
|
|
|
38002
38277
|
var orderUtils = OrderUtils$2;
|
|
38003
38278
|
|
|
38004
|
-
var address = "
|
|
38279
|
+
var address = "F2FzigE1Z374iDvreiM6hZQe6oGXgomJfv8PyybvUXye";
|
|
38005
38280
|
var metadata = {
|
|
38006
38281
|
name: "pinpet",
|
|
38007
38282
|
version: "0.1.0",
|
|
@@ -40486,7 +40761,7 @@
|
|
|
40486
40761
|
{
|
|
40487
40762
|
code: 6003,
|
|
40488
40763
|
name: "SellCalculationOverflow",
|
|
40489
|
-
msg: "Sell trade calculation
|
|
40764
|
+
msg: "Sell trade calculation overflow"
|
|
40490
40765
|
},
|
|
40491
40766
|
{
|
|
40492
40767
|
code: 6004,
|
|
@@ -41803,7 +42078,7 @@
|
|
|
41803
42078
|
this.pinPetFastApiUrl = this.options.pinPetFastApiUrl;
|
|
41804
42079
|
|
|
41805
42080
|
// Maximum number of orders that can be processed at once in the contract
|
|
41806
|
-
this.MAX_ORDERS_COUNT =
|
|
42081
|
+
this.MAX_ORDERS_COUNT = 50;
|
|
41807
42082
|
// Maximum number of orders to fetch during queries
|
|
41808
42083
|
this.FIND_MAX_ORDERS_COUNT = 1000;
|
|
41809
42084
|
|
|
@@ -41967,13 +42242,13 @@
|
|
|
41967
42242
|
LOCALNET: {
|
|
41968
42243
|
name: 'localnet',
|
|
41969
42244
|
defaultDataSource: 'fast', // 'fast' or 'chain'
|
|
41970
|
-
|
|
41971
|
-
|
|
41972
|
-
solanaEndpoint: 'http://162.250.124.66:8899',
|
|
41973
|
-
pinPetFastApiUrl: 'http://162.250.124.66:3000',
|
|
42245
|
+
solanaEndpoint: 'http://127.0.0.1:8899',
|
|
42246
|
+
pinPetFastApiUrl: 'http://127.0.0.1:3000',
|
|
42247
|
+
// solanaEndpoint: 'http://162.250.124.66:8899',
|
|
42248
|
+
// pinPetFastApiUrl: 'http://162.250.124.66:3000',
|
|
41974
42249
|
feeRecipient: 'GesAj2dTn2wdNcxj4x8qsqS9aNRVPBPkE76aaqg7skxu',
|
|
41975
42250
|
baseFeeRecipient: '5YHi1HsxobLiTD6NQfHJQpoPoRjMuNyXp4RroTvR6dKi',
|
|
41976
|
-
paramsAccount: '
|
|
42251
|
+
paramsAccount: '8tn4XdqWAAh97WwfLrDrwnagRsQp7Nu5nrUmXVBJvgMU'
|
|
41977
42252
|
}
|
|
41978
42253
|
};
|
|
41979
42254
|
|