@meteora-ag/dlmm 1.6.0-rc.0 → 1.6.0-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
@@ -12,7 +12,6 @@ import {
12
12
  } from "@solana/spl-token";
13
13
  import {
14
14
  ComputeBudgetProgram as ComputeBudgetProgram3,
15
- Keypair as Keypair2,
16
15
  LAMPORTS_PER_SOL as LAMPORTS_PER_SOL2,
17
16
  PublicKey as PublicKey10,
18
17
  SYSVAR_CLOCK_PUBKEY as SYSVAR_CLOCK_PUBKEY2,
@@ -12180,20 +12179,6 @@ function isPositionNoFee(position) {
12180
12179
  function isPositionNoReward(position) {
12181
12180
  return position.rewardOne.isZero() && position.rewardTwo.isZero();
12182
12181
  }
12183
- function chunkBinRangeIntoExtendedPositions(minBinId, maxBinId) {
12184
- const chunkedBinRange = [];
12185
- for (let currentMinBinId = minBinId; currentMinBinId <= maxBinId; currentMinBinId += POSITION_MAX_LENGTH.toNumber()) {
12186
- const currentMaxBinId = Math.min(
12187
- currentMinBinId + POSITION_MAX_LENGTH.toNumber() - 1,
12188
- maxBinId
12189
- );
12190
- chunkedBinRange.push({
12191
- lowerBinId: currentMinBinId,
12192
- upperBinId: currentMaxBinId
12193
- });
12194
- }
12195
- return chunkedBinRange;
12196
- }
12197
12182
  function chunkBinRange(minBinId, maxBinId) {
12198
12183
  const chunkedBinRange = [];
12199
12184
  let startBinId = minBinId;
@@ -15122,78 +15107,14 @@ var DLMM = class {
15122
15107
  lowerBinArrayIndex.add(new BN21(1))
15123
15108
  );
15124
15109
  const binArraysCount = (await this.binArraysToBeCreate(lowerBinArrayIndex, upperBinArrayIndex)).length;
15125
- const positionCount = Math.ceil(
15126
- (maxBinId - minBinId + 1) / Number(MAX_BINS_PER_POSITION)
15110
+ const transactionCount = Math.ceil(
15111
+ (maxBinId - minBinId + 1) / DEFAULT_BIN_PER_POSITION.toNumber()
15127
15112
  );
15128
15113
  const binArrayCost = binArraysCount * BIN_ARRAY_FEE;
15129
- const positionCost = positionCount * POSITION_FEE;
15130
15114
  return {
15131
15115
  binArraysCount,
15132
15116
  binArrayCost,
15133
- positionCount,
15134
- positionCost
15135
- };
15136
- }
15137
- /**
15138
- * Estimates the cost to create a new position based on the given strategy.
15139
- *
15140
- * This function calculates the costs associated with creating bin arrays, positions
15141
- * and extending positions for a specified range of bins.
15142
- *
15143
- * @param {TQuoteCreatePositionParams} param0 - The settings of the requested new position,
15144
- * including the strategy with minimum and maximum bin IDs.
15145
- * @returns An object containing:
15146
- * - binArraysCount: The number of bin arrays required.
15147
- * - binArrayCost: The estimated cost for creating bin arrays.
15148
- * - positionCount: The number of positions required.
15149
- * - positionCost: The fee cost for creating positions.
15150
- * - positionExtendCost: The rent cost in lamports for extending positions.
15151
- */
15152
- async quoteCreateMultiplePositions({
15153
- strategy
15154
- }) {
15155
- const { minBinId, maxBinId } = strategy;
15156
- const minBinIdBN = new BN21(minBinId);
15157
- const maxBinIdBN = new BN21(maxBinId);
15158
- const lowerBinArrayIndex = binIdToBinArrayIndex(minBinIdBN);
15159
- const upperBinArrayIndex = binIdToBinArrayIndex(maxBinIdBN);
15160
- const binArraysCount = (await this.binArraysToBeCreate(lowerBinArrayIndex, upperBinArrayIndex)).length;
15161
- const binArrayCost = new Decimal7(binArraysCount).mul(
15162
- new Decimal7(BIN_ARRAY_FEE)
15163
- );
15164
- let positionCost = new Decimal7(0);
15165
- let positionExtendCost = new Decimal7(0);
15166
- const chunkedPositionBinRange = chunkBinRangeIntoExtendedPositions(
15167
- minBinId,
15168
- maxBinId
15169
- );
15170
- const positionCount = chunkedPositionBinRange.length;
15171
- for (const { lowerBinId, upperBinId } of chunkedPositionBinRange) {
15172
- positionCost = positionCost.add(new Decimal7(POSITION_FEE));
15173
- const lowerBinIdBN = new BN21(lowerBinId);
15174
- const upperBinIdBN = new BN21(upperBinId);
15175
- const extendedBinCount = getExtendedPositionBinCount(
15176
- lowerBinIdBN,
15177
- upperBinIdBN
15178
- );
15179
- const upperBinIdBeforeExtend = upperBinIdBN.sub(extendedBinCount);
15180
- positionExtendCost = positionExtendCost.add(
15181
- await getPositionExpandRentExemption(
15182
- lowerBinIdBN,
15183
- upperBinIdBeforeExtend,
15184
- this.program.provider.connection,
15185
- extendedBinCount
15186
- ).then(
15187
- (lamports) => new Decimal7(lamports).div(new Decimal7(LAMPORTS_PER_SOL2))
15188
- )
15189
- );
15190
- }
15191
- return {
15192
- binArraysCount,
15193
- binArrayCost,
15194
- positionCount,
15195
- positionCost,
15196
- positionExtendCost
15117
+ transactionCount
15197
15118
  };
15198
15119
  }
15199
15120
  /**
@@ -15234,84 +15155,6 @@ var DLMM = class {
15234
15155
  feePayer: user
15235
15156
  }).add(setCUIx, ...instructions);
15236
15157
  }
15237
- /**
15238
- * Creates multiple empty positions for a user in specified bin ranges with necessary bin arrays.
15239
- *
15240
- * @param {number} minBinId - The minimum bin ID for the positions.
15241
- * @param {number} maxBinId - The maximum bin ID for the positions.
15242
- * @param {PublicKey} user - The public key of the user for whom the positions are created.
15243
- *
15244
- * @returns An object containing arrays of transactions for initializing positions, extending positions and initialzing bin arrays.
15245
- */
15246
- async createMultipleEmptyPositions({
15247
- minBinId,
15248
- maxBinId,
15249
- user
15250
- }) {
15251
- const chunkedBinRange = chunkBinRangeIntoExtendedPositions(
15252
- minBinId,
15253
- maxBinId
15254
- );
15255
- const positionCount = chunkedBinRange.length;
15256
- const positionKeypairs = [];
15257
- const initPositionIxs = [];
15258
- const initBinArrayIxs = [];
15259
- const binArrayIndexSet = /* @__PURE__ */ new Set();
15260
- for (let i = 0; i < positionCount; i++) {
15261
- const positionKeypair = Keypair2.generate();
15262
- positionKeypairs.push(positionKeypair);
15263
- const { lowerBinId, upperBinId } = chunkedBinRange[i];
15264
- let width = upperBinId - lowerBinId + 1;
15265
- width = Math.min(width, DEFAULT_BIN_PER_POSITION.toNumber());
15266
- const initPositionIx = await this.createInitAndExtendPositionIx(
15267
- lowerBinId,
15268
- upperBinId,
15269
- width,
15270
- user,
15271
- positionKeypair.publicKey
15272
- );
15273
- initPositionIxs.push(initPositionIx);
15274
- const binArrayIndexes = getBinArrayIndexesCoverage(
15275
- new BN21(lowerBinId),
15276
- new BN21(upperBinId)
15277
- ).filter((idx) => !binArrayIndexSet.has(idx.toNumber()));
15278
- const createBinArrayIxs = await this.createBinArraysIfNeeded(
15279
- binArrayIndexes,
15280
- user
15281
- ).then(
15282
- (ixs) => ixs.map((ix) => [
15283
- ComputeBudgetProgram3.setComputeUnitLimit({
15284
- units: DEFAULT_INIT_BIN_ARRAY_CU
15285
- }),
15286
- ix
15287
- ])
15288
- );
15289
- binArrayIndexes.map((idx) => {
15290
- binArrayIndexSet.add(idx.toNumber());
15291
- });
15292
- initBinArrayIxs.push(...createBinArrayIxs);
15293
- }
15294
- const { blockhash, lastValidBlockHeight } = await this.program.provider.connection.getLatestBlockhash("confirmed");
15295
- const initPositionTxs = initPositionIxs.map((ix) => {
15296
- return new Transaction({
15297
- blockhash,
15298
- lastValidBlockHeight,
15299
- feePayer: user
15300
- }).add(...ix);
15301
- });
15302
- const initBinArrayTxs = initBinArrayIxs.map((ix) => {
15303
- return new Transaction({
15304
- blockhash,
15305
- lastValidBlockHeight,
15306
- feePayer: user
15307
- }).add(...ix);
15308
- });
15309
- return {
15310
- positionKeypairs,
15311
- initPositionTxs,
15312
- initBinArrayTxs
15313
- };
15314
- }
15315
15158
  /**
15316
15159
  * The function `getPosition` retrieves position information for a given public key and processes it
15317
15160
  * using various data to return a `LbPosition` object.
@@ -18387,220 +18230,334 @@ var DLMM = class {
18387
18230
  const { lbPair, shouldClaimFee, shouldClaimReward, owner, address } = rebalancePosition;
18388
18231
  const { depositParams, withdrawParams } = simulationResult;
18389
18232
  const activeId = new BN21(lbPair.activeId);
18390
- const { slices, accounts: transferHookAccounts } = this.getPotentialToken2022IxDataAndAccounts(0 /* Liquidity */);
18391
- const preInstructions = [];
18392
- const harvestRewardRemainingAccountMetas = [];
18393
- if (shouldClaimReward) {
18394
- for (const [idx, reward] of this.lbPair.rewardInfos.entries()) {
18395
- if (!reward.mint.equals(PublicKey10.default)) {
18396
- const rewardTokenInfo = this.rewards[idx];
18397
- slices.push({
18398
- accountsType: {
18399
- transferHookMultiReward: {
18400
- 0: idx
18401
- }
18402
- },
18403
- length: rewardTokenInfo.transferHookAccountMetas.length
18404
- });
18405
- transferHookAccounts.push(
18406
- ...rewardTokenInfo.transferHookAccountMetas
18407
- );
18408
- const userTokenRewardAddress = getAssociatedTokenAddressSync2(
18409
- reward.mint,
18410
- owner,
18411
- true,
18412
- rewardTokenInfo.owner
18413
- );
18414
- preInstructions.push(
18415
- createAssociatedTokenAccountIdempotentInstruction2(
18416
- owner,
18417
- userTokenRewardAddress,
18418
- owner,
18233
+ let minBinId = Number.POSITIVE_INFINITY;
18234
+ let maxBinId = Number.NEGATIVE_INFINITY;
18235
+ for (const param of depositParams) {
18236
+ const min = activeId.toNumber() + param.minDeltaId;
18237
+ const max = activeId.toNumber() + param.maxDeltaId;
18238
+ if (min < minBinId)
18239
+ minBinId = min;
18240
+ if (max > maxBinId)
18241
+ maxBinId = max;
18242
+ }
18243
+ for (const param of withdrawParams) {
18244
+ if (param.minBinId !== null && param.minBinId < minBinId)
18245
+ minBinId = param.minBinId;
18246
+ if (param.maxBinId !== null && param.maxBinId > maxBinId)
18247
+ maxBinId = param.maxBinId;
18248
+ }
18249
+ if (!Number.isFinite(minBinId) || !Number.isFinite(maxBinId)) {
18250
+ throw new Error("Unable to determine min/max binId for chunking");
18251
+ }
18252
+ const binChunks = chunkBinRange(minBinId, maxBinId);
18253
+ function splitDepositParamsForChunk(params, chunk, activeId2) {
18254
+ const res = [];
18255
+ for (const param of params) {
18256
+ const absMin = activeId2.toNumber() + param.minDeltaId;
18257
+ const absMax = activeId2.toNumber() + param.maxDeltaId;
18258
+ if (absMax < chunk.lowerBinId || absMin > chunk.upperBinId)
18259
+ continue;
18260
+ const newMin = Math.max(absMin, chunk.lowerBinId);
18261
+ const newMax = Math.min(absMax, chunk.upperBinId);
18262
+ res.push({
18263
+ ...param,
18264
+ minDeltaId: newMin - activeId2.toNumber(),
18265
+ maxDeltaId: newMax - activeId2.toNumber()
18266
+ });
18267
+ }
18268
+ return res;
18269
+ }
18270
+ function splitWithdrawParamsForChunk(params, chunk) {
18271
+ const res = [];
18272
+ for (const param of params) {
18273
+ const absMin = param.minBinId !== null ? param.minBinId : activeId.toNumber();
18274
+ const absMax = param.maxBinId !== null ? param.maxBinId : activeId.toNumber();
18275
+ if (absMax < chunk.lowerBinId || absMin > chunk.upperBinId)
18276
+ continue;
18277
+ const newMin = Math.max(absMin, chunk.lowerBinId);
18278
+ const newMax = Math.min(absMax, chunk.upperBinId);
18279
+ res.push({
18280
+ ...param,
18281
+ minBinId: newMin,
18282
+ maxBinId: newMax
18283
+ });
18284
+ }
18285
+ return res;
18286
+ }
18287
+ const allInstructions = [];
18288
+ for (const chunk of binChunks) {
18289
+ const chunkedDepositParams = splitDepositParamsForChunk(
18290
+ depositParams,
18291
+ chunk,
18292
+ activeId
18293
+ );
18294
+ const chunkedWithdrawParams = splitWithdrawParamsForChunk(
18295
+ withdrawParams,
18296
+ chunk
18297
+ );
18298
+ if (chunkedDepositParams.length === 0 && chunkedWithdrawParams.length === 0)
18299
+ continue;
18300
+ const { slices, accounts: transferHookAccounts } = this.getPotentialToken2022IxDataAndAccounts(0 /* Liquidity */);
18301
+ const preInstructions = [];
18302
+ const harvestRewardRemainingAccountMetas = [];
18303
+ if (shouldClaimReward) {
18304
+ for (const [idx, reward] of this.lbPair.rewardInfos.entries()) {
18305
+ if (!reward.mint.equals(PublicKey10.default)) {
18306
+ const rewardTokenInfo = this.rewards[idx];
18307
+ slices.push({
18308
+ accountsType: {
18309
+ transferHookMultiReward: {
18310
+ 0: idx
18311
+ }
18312
+ },
18313
+ length: rewardTokenInfo.transferHookAccountMetas.length
18314
+ });
18315
+ transferHookAccounts.push(
18316
+ ...rewardTokenInfo.transferHookAccountMetas
18317
+ );
18318
+ const userTokenRewardAddress = getAssociatedTokenAddressSync2(
18419
18319
  reward.mint,
18320
+ owner,
18321
+ true,
18420
18322
  rewardTokenInfo.owner
18421
- )
18422
- );
18423
- const rewardVault = {
18424
- pubkey: reward.vault,
18425
- isSigner: false,
18426
- isWritable: true
18427
- };
18428
- const userTokenReward = {
18429
- pubkey: userTokenRewardAddress,
18430
- isSigner: false,
18431
- isWritable: true
18432
- };
18433
- const rewardMint = {
18434
- pubkey: reward.mint,
18435
- isSigner: false,
18436
- isWritable: false
18437
- };
18438
- const rewardTokenProgram = {
18439
- pubkey: rewardTokenInfo.owner,
18440
- isSigner: false,
18441
- isWritable: false
18442
- };
18443
- harvestRewardRemainingAccountMetas.push(
18444
- rewardVault,
18445
- userTokenReward,
18446
- rewardMint,
18447
- rewardTokenProgram
18448
- );
18323
+ );
18324
+ preInstructions.push(
18325
+ createAssociatedTokenAccountIdempotentInstruction2(
18326
+ owner,
18327
+ userTokenRewardAddress,
18328
+ owner,
18329
+ reward.mint,
18330
+ rewardTokenInfo.owner
18331
+ )
18332
+ );
18333
+ const rewardVault = {
18334
+ pubkey: reward.vault,
18335
+ isSigner: false,
18336
+ isWritable: true
18337
+ };
18338
+ const userTokenReward = {
18339
+ pubkey: userTokenRewardAddress,
18340
+ isSigner: false,
18341
+ isWritable: true
18342
+ };
18343
+ const rewardMint = {
18344
+ pubkey: reward.mint,
18345
+ isSigner: false,
18346
+ isWritable: false
18347
+ };
18348
+ const rewardTokenProgram = {
18349
+ pubkey: rewardTokenInfo.owner,
18350
+ isSigner: false,
18351
+ isWritable: false
18352
+ };
18353
+ harvestRewardRemainingAccountMetas.push(
18354
+ rewardVault,
18355
+ userTokenReward,
18356
+ rewardMint,
18357
+ rewardTokenProgram
18358
+ );
18359
+ }
18449
18360
  }
18450
18361
  }
18451
- }
18452
- const initBinArrayInstructions = [];
18453
- const { binArrayBitmap, binArrayIndexes } = getRebalanceBinArrayIndexesAndBitmapCoverage(
18454
- depositParams,
18455
- withdrawParams,
18456
- activeId.toNumber(),
18457
- this.pubkey,
18458
- this.program.programId
18459
- );
18460
- const binArrayPublicKeys = binArrayIndexes.map((index) => {
18461
- const [binArrayPubkey] = deriveBinArray(
18362
+ const initBinArrayInstructions = [];
18363
+ const { binArrayBitmap, binArrayIndexes } = getRebalanceBinArrayIndexesAndBitmapCoverage(
18364
+ chunkedDepositParams,
18365
+ chunkedWithdrawParams,
18366
+ activeId.toNumber(),
18462
18367
  this.pubkey,
18463
- index,
18464
18368
  this.program.programId
18465
18369
  );
18466
- return binArrayPubkey;
18467
- });
18468
- const binArrayAccounts = await chunkedGetMultipleAccountInfos(
18469
- this.program.provider.connection,
18470
- binArrayPublicKeys
18471
- );
18472
- for (let i = 0; i < binArrayAccounts.length; i++) {
18473
- const binArrayAccount = binArrayAccounts[i];
18474
- if (!binArrayAccount) {
18475
- const binArrayPubkey = binArrayPublicKeys[i];
18476
- const binArrayIndex = binArrayIndexes[i];
18477
- const initBinArrayIx = await this.program.methods.initializeBinArray(binArrayIndex).accountsPartial({
18478
- binArray: binArrayPubkey,
18479
- funder: owner,
18480
- lbPair: this.pubkey
18481
- }).instruction();
18482
- initBinArrayInstructions.push(initBinArrayIx);
18370
+ const binArrayPublicKeys = binArrayIndexes.map((index) => {
18371
+ const [binArrayPubkey] = deriveBinArray(
18372
+ this.pubkey,
18373
+ index,
18374
+ this.program.programId
18375
+ );
18376
+ return binArrayPubkey;
18377
+ });
18378
+ const binArrayAccounts = await chunkedGetMultipleAccountInfos(
18379
+ this.program.provider.connection,
18380
+ binArrayPublicKeys
18381
+ );
18382
+ for (let i = 0; i < binArrayAccounts.length; i++) {
18383
+ const binArrayAccount = binArrayAccounts[i];
18384
+ if (!binArrayAccount) {
18385
+ const binArrayPubkey = binArrayPublicKeys[i];
18386
+ const binArrayIndex = binArrayIndexes[i];
18387
+ const initBinArrayIx = await this.program.methods.initializeBinArray(binArrayIndex).accountsPartial({
18388
+ binArray: binArrayPubkey,
18389
+ funder: owner,
18390
+ lbPair: this.pubkey
18391
+ }).instruction();
18392
+ initBinArrayInstructions.push(initBinArrayIx);
18393
+ }
18483
18394
  }
18484
- }
18485
- if (!binArrayBitmap.equals(PublicKey10.default)) {
18486
- const bitmapAccount = await this.program.provider.connection.getAccountInfo(binArrayBitmap);
18487
- if (!bitmapAccount) {
18488
- const initBitmapExtensionIx = await this.program.methods.initializeBinArrayBitmapExtension().accountsPartial({
18489
- binArrayBitmapExtension: binArrayBitmap,
18490
- funder: owner,
18491
- lbPair: this.pubkey
18492
- }).preInstructions([
18493
- ComputeBudgetProgram3.setComputeUnitLimit({
18494
- units: DEFAULT_INIT_BIN_ARRAY_CU
18495
- })
18496
- ]).instruction();
18497
- preInstructions.push(initBitmapExtensionIx);
18395
+ if (!binArrayBitmap.equals(PublicKey10.default)) {
18396
+ const bitmapAccount = await this.program.provider.connection.getAccountInfo(binArrayBitmap);
18397
+ if (!bitmapAccount) {
18398
+ const initBitmapExtensionIx = await this.program.methods.initializeBinArrayBitmapExtension().accountsPartial({
18399
+ binArrayBitmapExtension: binArrayBitmap,
18400
+ funder: owner,
18401
+ lbPair: this.pubkey
18402
+ }).preInstructions([
18403
+ ComputeBudgetProgram3.setComputeUnitLimit({
18404
+ units: DEFAULT_INIT_BIN_ARRAY_CU
18405
+ })
18406
+ ]).instruction();
18407
+ preInstructions.push(initBitmapExtensionIx);
18408
+ }
18498
18409
  }
18499
- }
18500
- const userTokenX = getAssociatedTokenAddressSync2(
18501
- this.tokenX.publicKey,
18502
- owner,
18503
- true,
18504
- this.tokenX.owner
18505
- );
18506
- const userTokenY = getAssociatedTokenAddressSync2(
18507
- this.tokenY.publicKey,
18508
- owner,
18509
- true,
18510
- this.tokenY.owner
18511
- );
18512
- preInstructions.push(
18513
- createAssociatedTokenAccountIdempotentInstruction2(
18410
+ const [
18411
+ { ataPubKey: userTokenX, ix: createUserTokenXIx },
18412
+ { ataPubKey: userTokenY, ix: createUserTokenYIx }
18413
+ ] = await Promise.all([
18414
+ getOrCreateATAInstruction(
18415
+ this.program.provider.connection,
18416
+ this.tokenX.publicKey,
18417
+ owner,
18418
+ this.tokenX.owner
18419
+ ),
18420
+ getOrCreateATAInstruction(
18421
+ this.program.provider.connection,
18422
+ this.tokenY.publicKey,
18423
+ owner,
18424
+ this.tokenY.owner
18425
+ )
18426
+ ]);
18427
+ createUserTokenXIx && preInstructions.push(createUserTokenXIx);
18428
+ createUserTokenYIx && preInstructions.push(createUserTokenYIx);
18429
+ slippage = capSlippagePercentage(slippage);
18430
+ const applySlippageMaxAmount = (amount, slippage2) => {
18431
+ return slippage2 == 100 ? U64_MAX : amount.muln(100 + slippage2).divn(100);
18432
+ };
18433
+ const applySlippageMinAmount = (amount, slippage2) => {
18434
+ return amount.muln(100 - slippage2).divn(100);
18435
+ };
18436
+ const maxDepositXAmount = applySlippageMaxAmount(
18437
+ simulationResult.actualAmountXDeposited,
18438
+ slippage
18439
+ );
18440
+ const maxDepositYAmount = applySlippageMaxAmount(
18441
+ simulationResult.actualAmountYDeposited,
18442
+ slippage
18443
+ );
18444
+ const minWithdrawXAmount = applySlippageMinAmount(
18445
+ simulationResult.actualAmountXWithdrawn,
18446
+ slippage
18447
+ );
18448
+ const minWithdrawYAmount = applySlippageMinAmount(
18449
+ simulationResult.actualAmountYWithdrawn,
18450
+ slippage
18451
+ );
18452
+ const postInstructions = [];
18453
+ if (this.tokenX.publicKey.equals(NATIVE_MINT2) && simulationResult.actualAmountXDeposited.gtn(0)) {
18454
+ const wrapSOLIx = wrapSOLInstruction(
18455
+ owner,
18456
+ userTokenX,
18457
+ BigInt(simulationResult.actualAmountXDeposited.toString())
18458
+ );
18459
+ preInstructions.push(...wrapSOLIx);
18460
+ }
18461
+ if (this.tokenY.publicKey.equals(NATIVE_MINT2) && simulationResult.actualAmountYDeposited.gtn(0)) {
18462
+ const wrapSOLIx = wrapSOLInstruction(
18463
+ owner,
18464
+ userTokenY,
18465
+ BigInt(simulationResult.actualAmountYDeposited.toString())
18466
+ );
18467
+ preInstructions.push(...wrapSOLIx);
18468
+ }
18469
+ if (this.tokenX.publicKey.equals(NATIVE_MINT2) || this.tokenY.publicKey.equals(NATIVE_MINT2)) {
18470
+ const closeWrappedSOLIx = await unwrapSOLInstruction(owner);
18471
+ closeWrappedSOLIx && postInstructions.push(closeWrappedSOLIx);
18472
+ }
18473
+ const instruction = await this.program.methods.rebalanceLiquidity(
18474
+ {
18475
+ adds: chunkedDepositParams,
18476
+ removes: chunkedWithdrawParams,
18477
+ activeId: activeId.toNumber(),
18478
+ shouldClaimFee,
18479
+ shouldClaimReward,
18480
+ maxActiveBinSlippage: maxActiveBinSlippage.toNumber(),
18481
+ maxDepositXAmount,
18482
+ maxDepositYAmount,
18483
+ minWithdrawXAmount,
18484
+ minWithdrawYAmount,
18485
+ padding: Array(32).fill(0)
18486
+ },
18487
+ {
18488
+ slices
18489
+ }
18490
+ ).accountsPartial({
18491
+ lbPair: this.pubkey,
18492
+ binArrayBitmapExtension: binArrayBitmap,
18493
+ position: address,
18514
18494
  owner,
18515
18495
  userTokenX,
18516
- owner,
18517
- this.tokenX.publicKey,
18518
- this.tokenX.owner
18519
- )
18520
- );
18521
- preInstructions.push(
18522
- createAssociatedTokenAccountIdempotentInstruction2(
18523
- owner,
18524
18496
  userTokenY,
18525
- owner,
18526
- this.tokenY.publicKey,
18527
- this.tokenY.owner
18528
- )
18529
- );
18530
- slippage = capSlippagePercentage(slippage);
18531
- const applySlippageMaxAmount = (amount, slippage2) => {
18532
- return slippage2 == 100 ? U64_MAX : amount.muln(100 + slippage2).divn(100);
18533
- };
18534
- const applySlippageMinAmount = (amount, slippage2) => {
18535
- return amount.muln(100 - slippage2).divn(100);
18536
- };
18537
- const maxDepositXAmount = applySlippageMaxAmount(
18538
- simulationResult.actualAmountXDeposited,
18539
- slippage
18540
- );
18541
- const maxDepositYAmount = applySlippageMaxAmount(
18542
- simulationResult.actualAmountYDeposited,
18543
- slippage
18544
- );
18545
- const minWithdrawXAmount = applySlippageMinAmount(
18546
- simulationResult.actualAmountXWithdrawn,
18547
- slippage
18548
- );
18549
- const minWithdrawYAmount = applySlippageMinAmount(
18550
- simulationResult.actualAmountYWithdrawn,
18551
- slippage
18497
+ reserveX: this.lbPair.reserveX,
18498
+ reserveY: this.lbPair.reserveY,
18499
+ tokenXMint: this.tokenX.publicKey,
18500
+ tokenYMint: this.tokenY.publicKey,
18501
+ tokenXProgram: this.tokenX.owner,
18502
+ tokenYProgram: this.tokenY.owner,
18503
+ memoProgram: MEMO_PROGRAM_ID,
18504
+ rentPayer: rentPayer ?? owner
18505
+ }).remainingAccounts(transferHookAccounts).remainingAccounts(
18506
+ binArrayPublicKeys.map((pubkey) => {
18507
+ return {
18508
+ pubkey,
18509
+ isSigner: false,
18510
+ isWritable: true
18511
+ };
18512
+ })
18513
+ ).instruction();
18514
+ const setCUIX = await getEstimatedComputeUnitIxWithBuffer(
18515
+ this.program.provider.connection,
18516
+ [instruction],
18517
+ owner
18518
+ );
18519
+ const rebalancePositionInstruction = [
18520
+ setCUIX,
18521
+ ...preInstructions,
18522
+ instruction,
18523
+ ...postInstructions
18524
+ ];
18525
+ allInstructions.push({
18526
+ initBinArrayInstructions,
18527
+ rebalancePositionInstruction,
18528
+ chunk
18529
+ });
18530
+ }
18531
+ return allInstructions;
18532
+ }
18533
+ /**
18534
+ * Create an extended empty position.
18535
+ *
18536
+ * @param lowerBinid The lowest bin of the position.
18537
+ * @param upperBinId The highest bin of the position.
18538
+ * @param position The public key of the position.
18539
+ * @param owner The owner of the position.
18540
+ * @returns The instructions to create the extended empty position.
18541
+ */
18542
+ async createExtendedEmptyPosition(lowerBinid, upperBinId, position, owner) {
18543
+ const positionWidth = upperBinId - lowerBinid + 1;
18544
+ const basePositionWidth = Math.min(
18545
+ positionWidth,
18546
+ DEFAULT_BIN_PER_POSITION.toNumber()
18552
18547
  );
18553
- const instruction = await this.program.methods.rebalanceLiquidity(
18554
- {
18555
- adds: depositParams,
18556
- removes: withdrawParams,
18557
- activeId: activeId.toNumber(),
18558
- shouldClaimFee,
18559
- shouldClaimReward,
18560
- maxActiveBinSlippage: maxActiveBinSlippage.toNumber(),
18561
- maxDepositXAmount,
18562
- maxDepositYAmount,
18563
- minWithdrawXAmount,
18564
- minWithdrawYAmount,
18565
- padding: Array(32).fill(0)
18566
- },
18567
- {
18568
- slices
18569
- }
18570
- ).accountsPartial({
18571
- lbPair: this.pubkey,
18572
- binArrayBitmapExtension: binArrayBitmap,
18573
- position: address,
18548
+ const ixs = await this.createInitAndExtendPositionIx(
18549
+ lowerBinid,
18550
+ upperBinId,
18551
+ basePositionWidth,
18574
18552
  owner,
18575
- userTokenX,
18576
- userTokenY,
18577
- reserveX: this.lbPair.reserveX,
18578
- reserveY: this.lbPair.reserveY,
18579
- tokenXMint: this.tokenX.publicKey,
18580
- tokenYMint: this.tokenY.publicKey,
18581
- tokenXProgram: this.tokenX.owner,
18582
- tokenYProgram: this.tokenY.owner,
18583
- memoProgram: MEMO_PROGRAM_ID,
18584
- rentPayer: rentPayer ?? owner
18585
- }).preInstructions(preInstructions).remainingAccounts(transferHookAccounts).remainingAccounts(
18586
- binArrayPublicKeys.map((pubkey) => {
18587
- return {
18588
- pubkey,
18589
- isSigner: false,
18590
- isWritable: true
18591
- };
18592
- })
18593
- ).instruction();
18594
- const setCUIX = await getEstimatedComputeUnitIxWithBuffer(
18595
- this.program.provider.connection,
18596
- [instruction],
18597
- owner
18553
+ position
18598
18554
  );
18599
- const rebalancePositionInstruction = [setCUIX, instruction];
18600
- return {
18601
- initBinArrayInstructions,
18602
- rebalancePositionInstruction
18603
- };
18555
+ const latestBlockhashInfo = await this.program.provider.connection.getLatestBlockhash();
18556
+ const tx = new Transaction({
18557
+ ...latestBlockhashInfo,
18558
+ feePayer: owner
18559
+ }).add(...ixs);
18560
+ return tx;
18604
18561
  }
18605
18562
  async createInitAndExtendPositionIx(lowerBinId, upperBinId, basePositionWidth, user, position) {
18606
18563
  const createPositionIx = await this.program.methods.initializePosition(lowerBinId, basePositionWidth).accountsPartial({