@meteora-ag/dlmm 1.0.51 → 1.0.52-rc.10

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/index.mjs CHANGED
@@ -2048,6 +2048,73 @@ var IDL = {
2048
2048
  ],
2049
2049
  "args": []
2050
2050
  },
2051
+ {
2052
+ "name": "removeLiquiditySingleSide",
2053
+ "accounts": [
2054
+ {
2055
+ "name": "position",
2056
+ "isMut": true,
2057
+ "isSigner": false
2058
+ },
2059
+ {
2060
+ "name": "lbPair",
2061
+ "isMut": true,
2062
+ "isSigner": false
2063
+ },
2064
+ {
2065
+ "name": "binArrayBitmapExtension",
2066
+ "isMut": true,
2067
+ "isSigner": false,
2068
+ "isOptional": true
2069
+ },
2070
+ {
2071
+ "name": "userToken",
2072
+ "isMut": true,
2073
+ "isSigner": false
2074
+ },
2075
+ {
2076
+ "name": "reserve",
2077
+ "isMut": true,
2078
+ "isSigner": false
2079
+ },
2080
+ {
2081
+ "name": "tokenMint",
2082
+ "isMut": false,
2083
+ "isSigner": false
2084
+ },
2085
+ {
2086
+ "name": "binArrayLower",
2087
+ "isMut": true,
2088
+ "isSigner": false
2089
+ },
2090
+ {
2091
+ "name": "binArrayUpper",
2092
+ "isMut": true,
2093
+ "isSigner": false
2094
+ },
2095
+ {
2096
+ "name": "sender",
2097
+ "isMut": false,
2098
+ "isSigner": true
2099
+ },
2100
+ {
2101
+ "name": "tokenProgram",
2102
+ "isMut": false,
2103
+ "isSigner": false
2104
+ },
2105
+ {
2106
+ "name": "eventAuthority",
2107
+ "isMut": false,
2108
+ "isSigner": false
2109
+ },
2110
+ {
2111
+ "name": "program",
2112
+ "isMut": false,
2113
+ "isSigner": false
2114
+ }
2115
+ ],
2116
+ "args": []
2117
+ },
2051
2118
  {
2052
2119
  "name": "togglePairStatus",
2053
2120
  "accounts": [
@@ -3724,38 +3791,38 @@ var IDL = {
3724
3791
  }
3725
3792
  },
3726
3793
  {
3727
- "name": "BinLiquidityReduction",
3794
+ "name": "FeeParameter",
3728
3795
  "type": {
3729
3796
  "kind": "struct",
3730
3797
  "fields": [
3731
3798
  {
3732
- "name": "binId",
3733
- "type": "i32"
3799
+ "name": "protocolShare",
3800
+ "docs": [
3801
+ "Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee"
3802
+ ],
3803
+ "type": "u16"
3734
3804
  },
3735
3805
  {
3736
- "name": "bpsToRemove",
3806
+ "name": "baseFactor",
3807
+ "docs": [
3808
+ "Base factor for base fee rate"
3809
+ ],
3737
3810
  "type": "u16"
3738
3811
  }
3739
3812
  ]
3740
3813
  }
3741
3814
  },
3742
3815
  {
3743
- "name": "FeeParameter",
3816
+ "name": "BinLiquidityReduction",
3744
3817
  "type": {
3745
3818
  "kind": "struct",
3746
3819
  "fields": [
3747
3820
  {
3748
- "name": "protocolShare",
3749
- "docs": [
3750
- "Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee"
3751
- ],
3752
- "type": "u16"
3821
+ "name": "binId",
3822
+ "type": "i32"
3753
3823
  },
3754
3824
  {
3755
- "name": "baseFactor",
3756
- "docs": [
3757
- "Base factor for base fee rate"
3758
- ],
3825
+ "name": "bpsToRemove",
3759
3826
  "type": "u16"
3760
3827
  }
3761
3828
  ]
@@ -8503,17 +8570,6 @@ var DLMM = class {
8503
8570
  );
8504
8571
  return activeBinState;
8505
8572
  }
8506
- /**
8507
- * The function get the price of a bin based on its bin ID.
8508
- * @param {number} binId - The `binId` parameter is a number that represents the ID of a bin.
8509
- * @returns {number} the calculated price of a bin based on the provided binId.
8510
- */
8511
- getPriceOfBinByBinId(binId) {
8512
- const binStepNum = new Decimal4(this.lbPair.binStep).div(
8513
- new Decimal4(BASIS_POINT_MAX)
8514
- );
8515
- return new Decimal4(1).add(new Decimal4(binStepNum)).pow(new Decimal4(binId)).toString();
8516
- }
8517
8573
  /**
8518
8574
  * The function get bin ID based on a given price and a boolean flag indicating whether to
8519
8575
  * round down or up.
@@ -9604,6 +9660,76 @@ var DLMM = class {
9604
9660
  }).add(removeLiquidityTx);
9605
9661
  }
9606
9662
  }
9663
+ async removeLiquiditySingleSide({
9664
+ user,
9665
+ position,
9666
+ binIds,
9667
+ removeLiquidityForY = false
9668
+ }) {
9669
+ const { lbPair, lowerBinId, owner, feeOwner } = await this.program.account.positionV2.fetch(position);
9670
+ const { reserveX, reserveY, tokenXMint, tokenYMint } = await this.program.account.lbPair.fetch(lbPair);
9671
+ const lowerBinArrayIndex = binIdToBinArrayIndex(new BN9(lowerBinId));
9672
+ const upperBinArrayIndex = lowerBinArrayIndex.add(new BN9(1));
9673
+ const [binArrayLower] = deriveBinArray(
9674
+ lbPair,
9675
+ lowerBinArrayIndex,
9676
+ this.program.programId
9677
+ );
9678
+ const [binArrayUpper] = deriveBinArray(
9679
+ lbPair,
9680
+ upperBinArrayIndex,
9681
+ this.program.programId
9682
+ );
9683
+ const preInstructions = [];
9684
+ const setComputeUnitLimitIx = computeBudgetIx();
9685
+ preInstructions.push(setComputeUnitLimitIx);
9686
+ const { ataPubKey: userToken, ix: createPayerTokenIx } = removeLiquidityForY ? await getOrCreateATAInstruction(
9687
+ this.program.provider.connection,
9688
+ this.tokenY.publicKey,
9689
+ owner,
9690
+ user
9691
+ ) : await getOrCreateATAInstruction(
9692
+ this.program.provider.connection,
9693
+ this.tokenX.publicKey,
9694
+ owner,
9695
+ user
9696
+ );
9697
+ createPayerTokenIx && preInstructions.push(createPayerTokenIx);
9698
+ const postInstructions = [];
9699
+ if ([
9700
+ this.tokenX.publicKey.toBase58(),
9701
+ this.tokenY.publicKey.toBase58()
9702
+ ].includes(NATIVE_MINT2.toBase58())) {
9703
+ const closeWrappedSOLIx = await unwrapSOLInstruction(user);
9704
+ closeWrappedSOLIx && postInstructions.push(closeWrappedSOLIx);
9705
+ }
9706
+ const minBinId = Math.min(...binIds);
9707
+ const maxBinId = Math.max(...binIds);
9708
+ const minBinArrayIndex = binIdToBinArrayIndex(new BN9(minBinId));
9709
+ const maxBinArrayIndex = binIdToBinArrayIndex(new BN9(maxBinId));
9710
+ const useExtension = isOverflowDefaultBinArrayBitmap(minBinArrayIndex) || isOverflowDefaultBinArrayBitmap(maxBinArrayIndex);
9711
+ const binArrayBitmapExtension = useExtension ? deriveBinArrayBitmapExtension(this.pubkey, this.program.programId)[0] : null;
9712
+ const reserve = removeLiquidityForY ? reserveY : reserveX;
9713
+ const tokenMint = removeLiquidityForY ? tokenYMint : tokenXMint;
9714
+ const removeLiquiditySingleSideTx = await this.program.methods.removeLiquiditySingleSide().accounts({
9715
+ position,
9716
+ lbPair,
9717
+ binArrayBitmapExtension,
9718
+ userToken,
9719
+ reserve,
9720
+ tokenMint,
9721
+ binArrayLower,
9722
+ binArrayUpper,
9723
+ sender: user,
9724
+ tokenProgram: TOKEN_PROGRAM_ID2
9725
+ }).preInstructions(preInstructions).transaction();
9726
+ const { blockhash, lastValidBlockHeight } = await this.program.provider.connection.getLatestBlockhash("confirmed");
9727
+ return new Transaction({
9728
+ blockhash,
9729
+ lastValidBlockHeight,
9730
+ feePayer: user
9731
+ }).add(removeLiquiditySingleSideTx);
9732
+ }
9607
9733
  /**
9608
9734
  * The `closePosition` function closes a position
9609
9735
  * @param
@@ -9722,9 +9848,15 @@ var DLMM = class {
9722
9848
  }
9723
9849
  }
9724
9850
  }
9725
- const startPrice = this.getPriceOfBinByBinId(startBinId.toNumber());
9726
- const endPrice = this.getPriceOfBinByBinId(activeId.toNumber());
9727
- const priceImpact = new Decimal4(startPrice).sub(new Decimal4(endPrice)).abs().div(new Decimal4(startPrice)).mul(new Decimal4(100));
9851
+ const startPrice = getPriceOfBinByBinId(
9852
+ startBinId.toNumber(),
9853
+ this.lbPair.binStep
9854
+ );
9855
+ const endPrice = getPriceOfBinByBinId(
9856
+ activeId.toNumber(),
9857
+ this.lbPair.binStep
9858
+ );
9859
+ const priceImpact = startPrice.sub(endPrice).abs().div(startPrice).mul(new Decimal4(100));
9728
9860
  const maxInAmount = actualInAmount.mul(new BN9(BASIS_POINT_MAX).add(allowedSlippage)).div(new BN9(BASIS_POINT_MAX));
9729
9861
  return {
9730
9862
  inAmount: actualInAmount,
@@ -9835,6 +9967,10 @@ var DLMM = class {
9835
9967
  );
9836
9968
  const priceImpact = new Decimal4(actualOutAmount.toString()).sub(new Decimal4(outAmountWithoutSlippage.toString())).div(new Decimal4(outAmountWithoutSlippage.toString())).mul(new Decimal4(100));
9837
9969
  const minOutAmount = actualOutAmount.mul(new BN9(BASIS_POINT_MAX).sub(allowedSlippage)).div(new BN9(BASIS_POINT_MAX));
9970
+ const endPrice = getPriceOfBinByBinId(
9971
+ activeId.toNumber(),
9972
+ this.lbPair.binStep
9973
+ );
9838
9974
  return {
9839
9975
  consumedInAmount: inAmount,
9840
9976
  outAmount: actualOutAmount,
@@ -9842,7 +9978,8 @@ var DLMM = class {
9842
9978
  protocolFee: protocolFeeAmount,
9843
9979
  minOutAmount,
9844
9980
  priceImpact,
9845
- binArraysPubkey: [...binArraysForSwap.keys()]
9981
+ binArraysPubkey: [...binArraysForSwap.keys()],
9982
+ endPrice
9846
9983
  };
9847
9984
  }
9848
9985
  async swapExactOut({
@@ -10823,6 +10960,108 @@ var DLMM = class {
10823
10960
  Number(binPriceWithLastLiquidity) / (2 ** 64 - 1)
10824
10961
  );
10825
10962
  }
10963
+ getAmountOutWithdrawSingleSide(maxLiquidityShare, price, bin, isWithdrawForY) {
10964
+ const amountX = mulDiv(
10965
+ maxLiquidityShare,
10966
+ bin.amountX,
10967
+ bin.liquiditySupply,
10968
+ 1 /* Down */
10969
+ );
10970
+ const amountY = mulDiv(
10971
+ maxLiquidityShare,
10972
+ bin.amountY,
10973
+ bin.liquiditySupply,
10974
+ 1 /* Down */
10975
+ );
10976
+ const amount0 = isWithdrawForY ? amountX : amountY;
10977
+ const amount1 = isWithdrawForY ? amountY : amountX;
10978
+ const remainAmountX = bin.amountX.sub(amountX);
10979
+ const remainAmountY = bin.amountY.sub(amountY);
10980
+ if (amount0.eq(new BN9(0))) {
10981
+ return {
10982
+ withdrawAmount: amount1
10983
+ };
10984
+ }
10985
+ let maxAmountOut = isWithdrawForY ? remainAmountY : remainAmountX;
10986
+ let maxAmountIn = isWithdrawForY ? shlDiv(remainAmountY, price, SCALE_OFFSET, 0 /* Up */) : mulShr(remainAmountX, price, SCALE_OFFSET, 0 /* Up */);
10987
+ let maxFee = computeFee(
10988
+ this.lbPair.binStep,
10989
+ this.lbPair.parameters,
10990
+ this.lbPair.vParameters,
10991
+ maxAmountIn
10992
+ );
10993
+ maxAmountIn = maxAmountIn.add(maxFee);
10994
+ if (amount0.gt(maxAmountIn)) {
10995
+ return {
10996
+ withdrawAmount: maxAmountOut
10997
+ };
10998
+ }
10999
+ const fee = computeFeeFromAmount(
11000
+ this.lbPair.binStep,
11001
+ this.lbPair.parameters,
11002
+ this.lbPair.vParameters,
11003
+ amount0
11004
+ );
11005
+ const amount0AfterFee = amount0.sub(fee);
11006
+ const amountOut = isWithdrawForY ? mulShr(price, amount0AfterFee, SCALE_OFFSET, 1 /* Down */) : shlDiv(amount0AfterFee, price, SCALE_OFFSET, 1 /* Down */);
11007
+ return {
11008
+ withdrawAmount: amount1.add(amountOut.gt(maxAmountOut) ? maxAmountOut : amountOut)
11009
+ };
11010
+ }
11011
+ async getWithdrawSingleSideAmount(positionPubkey, isWithdrawForY) {
11012
+ let totalWithdrawAmount = new BN9(0);
11013
+ let lowerBinArray;
11014
+ let upperBinArray;
11015
+ const position = await this.program.account.positionV2.fetch(
11016
+ positionPubkey
11017
+ );
11018
+ const lowerBinArrayIdx = binIdToBinArrayIndex(new BN9(position.lowerBinId));
11019
+ const [lowerBinArrayPubKey] = deriveBinArray(
11020
+ position.lbPair,
11021
+ lowerBinArrayIdx,
11022
+ this.program.programId
11023
+ );
11024
+ const upperBinArrayIdx = lowerBinArrayIdx.add(new BN9(1));
11025
+ const [upperBinArrayPubKey] = deriveBinArray(
11026
+ position.lbPair,
11027
+ upperBinArrayIdx,
11028
+ this.program.programId
11029
+ );
11030
+ [lowerBinArray, upperBinArray] = await this.program.account.binArray.fetchMultiple([
11031
+ lowerBinArrayPubKey,
11032
+ upperBinArrayPubKey
11033
+ ]);
11034
+ if (!lowerBinArray || !upperBinArray)
11035
+ throw new Error("BinArray not found");
11036
+ for (let idx = 0; idx < position.liquidityShares.length; idx++) {
11037
+ const shareToRemove = position.liquidityShares[idx];
11038
+ if (shareToRemove.eq(new BN9(0))) {
11039
+ continue;
11040
+ }
11041
+ const binId = new BN9(position.lowerBinId).add(new BN9(idx));
11042
+ const binArrayIndex = binIdToBinArrayIndex(binId);
11043
+ const binArray = binArrayIndex.eq(lowerBinArrayIdx) ? lowerBinArray : upperBinArray;
11044
+ const bin = getBinFromBinArray(binId.toNumber(), binArray);
11045
+ if (isWithdrawForY) {
11046
+ if (binId.gt(new BN9(this.lbPair.activeId))) {
11047
+ break;
11048
+ }
11049
+ } else {
11050
+ if (binId.lt(new BN9(this.lbPair.activeId))) {
11051
+ continue;
11052
+ }
11053
+ }
11054
+ const price = getQPriceFromId(binId, new BN9(this.lbPair.binStep));
11055
+ const { withdrawAmount } = this.getAmountOutWithdrawSingleSide(
11056
+ shareToRemove,
11057
+ price,
11058
+ bin,
11059
+ isWithdrawForY
11060
+ );
11061
+ totalWithdrawAmount = totalWithdrawAmount.add(withdrawAmount);
11062
+ }
11063
+ return totalWithdrawAmount;
11064
+ }
10826
11065
  /** Private static method */
10827
11066
  static async getBinArrays(program, lbPairPubkey) {
10828
11067
  return program.account.binArray.all([
@@ -11049,10 +11288,10 @@ var DLMM = class {
11049
11288
  binArray.bins.forEach((bin, idx) => {
11050
11289
  const binId = lowerBinIdForBinArray.toNumber() + idx;
11051
11290
  if (binId >= lowerBinId && binId <= upperBinId) {
11052
- const pricePerLamport = this.getPriceOfBinByBinId(
11053
- lbPair.binStep,
11054
- binId
11055
- );
11291
+ const pricePerLamport = getPriceOfBinByBinId(
11292
+ binId,
11293
+ lbPair.binStep
11294
+ ).toString();
11056
11295
  bins.push({
11057
11296
  binId,
11058
11297
  xAmount: bin.amountX,
@@ -11073,10 +11312,10 @@ var DLMM = class {
11073
11312
  binArray.bins.forEach((bin, idx) => {
11074
11313
  const binId = lowerBinIdForBinArray.toNumber() + idx;
11075
11314
  if (binId >= lowerBinId && binId <= upperBinId) {
11076
- const pricePerLamport = this.getPriceOfBinByBinId(
11077
- lbPair.binStep,
11078
- binId
11079
- );
11315
+ const pricePerLamport = getPriceOfBinByBinId(
11316
+ binId,
11317
+ lbPair.binStep
11318
+ ).toString();
11080
11319
  bins.push({
11081
11320
  binId,
11082
11321
  xAmount: bin.amountX,
@@ -11092,10 +11331,6 @@ var DLMM = class {
11092
11331
  }
11093
11332
  return bins;
11094
11333
  }
11095
- static getPriceOfBinByBinId(binStep, binId) {
11096
- const binStepNum = new Decimal4(binStep).div(new Decimal4(BASIS_POINT_MAX));
11097
- return new Decimal4(1).add(new Decimal4(binStepNum)).pow(new Decimal4(binId)).toString();
11098
- }
11099
11334
  /** Private method */
11100
11335
  processXYAmountDistribution(xYAmountDistribution) {
11101
11336
  let currentBinId = null;
@@ -11134,8 +11369,6 @@ var DLMM = class {
11134
11369
  const [lowerBinId2, upperBinId2] = getBinArrayLowerUpperBinId(lowerBinArrayIndex);
11135
11370
  const binArrayBins = [];
11136
11371
  for (let i = lowerBinId2.toNumber(); i <= upperBinId2.toNumber(); i++) {
11137
- const binId = new BN9(i);
11138
- const pricePerLamport = this.getPriceOfBinByBinId(binId.toNumber());
11139
11372
  binArrayBins.push({
11140
11373
  amountX: new BN9(0),
11141
11374
  amountY: new BN9(0),
@@ -11160,7 +11393,10 @@ var DLMM = class {
11160
11393
  binArray.bins.forEach((bin, idx) => {
11161
11394
  const binId = lowerBinIdForBinArray.toNumber() + idx;
11162
11395
  if (binId >= lowerBinId && binId <= upperBinId) {
11163
- const pricePerLamport = this.getPriceOfBinByBinId(binId);
11396
+ const pricePerLamport = getPriceOfBinByBinId(
11397
+ binId,
11398
+ this.lbPair.binStep
11399
+ ).toString();
11164
11400
  bins.push({
11165
11401
  binId,
11166
11402
  xAmount: bin.amountX,
@@ -11201,7 +11437,10 @@ var DLMM = class {
11201
11437
  binArray.bins.forEach((bin, idx) => {
11202
11438
  const binId = lowerBinIdForBinArray.toNumber() + idx;
11203
11439
  if (binId >= lowerBinId && binId <= upperBinId) {
11204
- const pricePerLamport = this.getPriceOfBinByBinId(binId);
11440
+ const pricePerLamport = getPriceOfBinByBinId(
11441
+ binId,
11442
+ this.lbPair.binStep
11443
+ ).toString();
11205
11444
  bins.push({
11206
11445
  binId,
11207
11446
  xAmount: bin.amountX,