@meteora-ag/zap-sdk 1.2.0 → 1.3.0

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.js CHANGED
@@ -114,6 +114,8 @@ __export(index_exports, {
114
114
  getOrCreateATAInstruction: () => getOrCreateATAInstruction,
115
115
  getTokenAccountBalance: () => getTokenAccountBalance,
116
116
  getTokenProgramFromMint: () => getTokenProgramFromMint,
117
+ isSingleSidedA: () => isSingleSidedA,
118
+ isSingleSidedB: () => isSingleSidedB,
117
119
  toProgramStrategyType: () => toProgramStrategyType,
118
120
  unwrapSOLInstruction: () => unwrapSOLInstruction,
119
121
  wrapSOLInstruction: () => wrapSOLInstruction
@@ -1792,9 +1794,8 @@ function getJupiterQuote(_0, _1, _2, _3, _4) {
1792
1794
  dynamicSlippage: dynamicSlippage.toString()
1793
1795
  });
1794
1796
  const url = `${config.jupiterApiUrl || DEFAULT_JUPITER_API_URL}/swap/v1/quote?${params.toString()}`;
1795
- let response = null;
1796
1797
  try {
1797
- response = yield fetch(url, {
1798
+ const response = yield fetch(url, {
1798
1799
  method: "GET",
1799
1800
  headers: __spreadValues({
1800
1801
  Accept: "application/json"
@@ -1803,11 +1804,11 @@ function getJupiterQuote(_0, _1, _2, _3, _4) {
1803
1804
  if (!response.ok) {
1804
1805
  return null;
1805
1806
  }
1807
+ const result = yield response.json();
1808
+ return result;
1806
1809
  } catch (error) {
1807
1810
  return null;
1808
1811
  }
1809
- const result = yield response.json();
1810
- return result;
1811
1812
  });
1812
1813
  }
1813
1814
  function getJupiterSwapInstruction(_0, _1) {
@@ -1993,6 +1994,12 @@ function getDammV2RemainingAccounts(_0, _1, _2, _3) {
1993
1994
  return remainingAccounts;
1994
1995
  });
1995
1996
  }
1997
+ function isSingleSidedA(poolState) {
1998
+ return poolState.collectFeeMode !== import_cp_amm_sdk.CollectFeeMode.Compounding && poolState.sqrtPrice.eq(poolState.sqrtMinPrice);
1999
+ }
2000
+ function isSingleSidedB(poolState) {
2001
+ return poolState.collectFeeMode !== import_cp_amm_sdk.CollectFeeMode.Compounding && poolState.sqrtPrice.eq(poolState.sqrtMaxPrice);
2002
+ }
1996
2003
  function createDammV2SwapPayload(amountIn, minimumSwapAmountOut) {
1997
2004
  return Buffer.concat([
1998
2005
  Buffer.from(DAMM_V2_SWAP_DISCRIMINATOR),
@@ -3526,30 +3533,76 @@ var Zap = class {
3526
3533
  tokenBProgram
3527
3534
  );
3528
3535
  const inputTokenDecimal = inputTokenMint.equals(tokenAMint) ? tokenADecimal : tokenBDecimal;
3536
+ const collectFeeMode = poolState.collectFeeMode;
3529
3537
  const poolBalanceTokenA = (0, import_cp_amm_sdk3.getAmountAFromLiquidityDelta)(
3530
3538
  poolState.sqrtPrice,
3531
3539
  poolState.sqrtMaxPrice,
3532
3540
  poolState.liquidity,
3533
- import_cp_amm_sdk3.Rounding.Down
3541
+ import_cp_amm_sdk3.Rounding.Down,
3542
+ collectFeeMode,
3543
+ poolState.tokenAAmount,
3544
+ poolState.liquidity
3534
3545
  );
3535
3546
  const poolBalanceTokenB = (0, import_cp_amm_sdk3.getAmountBFromLiquidityDelta)(
3536
3547
  poolState.sqrtMinPrice,
3537
3548
  poolState.sqrtPrice,
3538
3549
  poolState.liquidity,
3539
- import_cp_amm_sdk3.Rounding.Down
3550
+ import_cp_amm_sdk3.Rounding.Down,
3551
+ collectFeeMode,
3552
+ poolState.tokenBAmount,
3553
+ poolState.liquidity
3540
3554
  );
3555
+ const isInputTokenA = tokenAMint.equals(inputTokenMint);
3556
+ const outputTokenMint = isInputTokenA ? tokenBMint : tokenAMint;
3557
+ const singleSidedA = isSingleSidedA(poolState);
3558
+ const singleSidedB = isSingleSidedB(poolState);
3541
3559
  let amount;
3542
3560
  let swapTransactions = [];
3543
3561
  let maxTransferAmount;
3544
3562
  let swapInAmount;
3545
3563
  let swapRoute;
3546
- if (dammV2Quote === null && jupiterQuote === null) {
3547
- throw new Error("No Jupiter or DAMM v2 quote found, unable to proceed");
3548
- }
3549
- if (jupiterQuote !== null && (dammV2Quote === null || new import_anchor.BN(jupiterQuote.outAmount).gte(dammV2Quote.swapOutAmount))) {
3564
+ if (singleSidedA && isInputTokenA || singleSidedB && !isInputTokenA) {
3565
+ amount = amountIn;
3566
+ swapInAmount = new import_anchor.BN(0);
3567
+ maxTransferAmount = new import_anchor.BN(0);
3568
+ swapRoute = "dammV2" /* DammV2 */;
3569
+ } else if (singleSidedA && !isInputTokenA || singleSidedB && isInputTokenA) {
3570
+ if (jupiterQuote !== null && (dammV2Quote === null || new import_anchor.BN(jupiterQuote.outAmount).gte(dammV2Quote.swapOutAmount))) {
3571
+ swapInAmount = amountIn;
3572
+ amount = new import_anchor.BN(0);
3573
+ const result = yield buildJupiterSwapTransaction(
3574
+ user,
3575
+ inputTokenMint,
3576
+ outputTokenMint,
3577
+ swapInAmount,
3578
+ maxAccounts,
3579
+ slippageBps,
3580
+ void 0,
3581
+ {
3582
+ jupiterApiUrl: this.jupiterApiUrl,
3583
+ jupiterApiKey: this.jupiterApiKey
3584
+ }
3585
+ );
3586
+ swapTransactions = [result.transaction];
3587
+ maxTransferAmount = getExtendMaxAmountTransfer(
3588
+ result.quoteResponse.outAmount,
3589
+ maxTransferAmountExtendPercentage
3590
+ );
3591
+ swapRoute = "jupiter" /* Jupiter */;
3592
+ } else if (dammV2Quote !== null) {
3593
+ swapInAmount = new import_anchor.BN(0);
3594
+ amount = amountIn;
3595
+ maxTransferAmount = new import_anchor.BN(0);
3596
+ swapRoute = "dammV2" /* DammV2 */;
3597
+ } else {
3598
+ throw new Error(
3599
+ "No Jupiter or DAMM v2 quote found for single-sided swap, unable to proceed"
3600
+ );
3601
+ }
3602
+ } else if (jupiterQuote !== null && (dammV2Quote === null || new import_anchor.BN(jupiterQuote.outAmount).gte(dammV2Quote.swapOutAmount))) {
3550
3603
  const price = convertLamportsToUiAmount(
3551
3604
  new import_decimal4.default(jupiterQuote.outAmount),
3552
- tokenAMint.equals(inputTokenMint) ? tokenBDecimal : tokenADecimal
3605
+ isInputTokenA ? tokenBDecimal : tokenADecimal
3553
3606
  );
3554
3607
  swapInAmount = calculateDirectPoolSwapAmount(
3555
3608
  amountIn,
@@ -3563,13 +3616,13 @@ var Zap = class {
3563
3616
  new import_decimal4.default(poolBalanceTokenB.toString()),
3564
3617
  tokenBDecimal
3565
3618
  ),
3566
- tokenAMint.equals(inputTokenMint)
3619
+ isInputTokenA
3567
3620
  );
3568
3621
  amount = amountIn.sub(swapInAmount);
3569
3622
  const result = yield buildJupiterSwapTransaction(
3570
3623
  user,
3571
3624
  inputTokenMint,
3572
- tokenAMint.equals(inputTokenMint) ? tokenBMint : tokenAMint,
3625
+ outputTokenMint,
3573
3626
  swapInAmount,
3574
3627
  maxAccounts,
3575
3628
  slippageBps,
@@ -3585,7 +3638,7 @@ var Zap = class {
3585
3638
  maxTransferAmountExtendPercentage
3586
3639
  );
3587
3640
  swapRoute = "jupiter" /* Jupiter */;
3588
- } else {
3641
+ } else if (dammV2Quote !== null) {
3589
3642
  const quote = dammV2Quote;
3590
3643
  amount = amountIn;
3591
3644
  const price = convertLamportsToUiAmount(
@@ -3604,13 +3657,15 @@ var Zap = class {
3604
3657
  new import_decimal4.default(poolBalanceTokenB.toString()),
3605
3658
  tokenBDecimal
3606
3659
  ),
3607
- tokenAMint.equals(inputTokenMint)
3660
+ isInputTokenA
3608
3661
  );
3609
3662
  maxTransferAmount = getExtendMaxAmountTransfer(
3610
3663
  quote.swapOutAmount.toString(),
3611
3664
  maxTransferAmountExtendPercentage
3612
3665
  );
3613
3666
  swapRoute = "dammV2" /* DammV2 */;
3667
+ } else {
3668
+ throw new Error("No Jupiter or DAMM v2 quote found, unable to proceed");
3614
3669
  }
3615
3670
  const cleanUpInstructions = [];
3616
3671
  if (tokenAMint.equals(import_spl_token6.NATIVE_MINT) || tokenBMint.equals(import_spl_token6.NATIVE_MINT)) {
@@ -3624,7 +3679,7 @@ var Zap = class {
3624
3679
  position,
3625
3680
  positionNftAccount,
3626
3681
  isDirectPool: true,
3627
- isTokenA: tokenAMint.equals(inputTokenMint),
3682
+ isTokenA: isInputTokenA,
3628
3683
  tokenAMint,
3629
3684
  tokenBMint,
3630
3685
  tokenAVault,
@@ -3735,20 +3790,131 @@ var Zap = class {
3735
3790
  const closewrapSol = unwrapSOLInstruction(user, user, false);
3736
3791
  closewrapSol && cleanUpInstructions.push(closewrapSol);
3737
3792
  }
3793
+ const collectFeeMode = poolState.collectFeeMode;
3738
3794
  const poolBalanceTokenA = (0, import_cp_amm_sdk3.getAmountAFromLiquidityDelta)(
3739
3795
  poolState.sqrtPrice,
3740
3796
  poolState.sqrtMaxPrice,
3741
3797
  poolState.liquidity,
3742
- import_cp_amm_sdk3.Rounding.Down
3798
+ import_cp_amm_sdk3.Rounding.Down,
3799
+ collectFeeMode,
3800
+ poolState.tokenAAmount,
3801
+ poolState.liquidity
3743
3802
  );
3744
3803
  const poolBalanceTokenB = (0, import_cp_amm_sdk3.getAmountBFromLiquidityDelta)(
3745
3804
  poolState.sqrtMinPrice,
3746
3805
  poolState.sqrtPrice,
3747
3806
  poolState.liquidity,
3748
- import_cp_amm_sdk3.Rounding.Down
3807
+ import_cp_amm_sdk3.Rounding.Down,
3808
+ collectFeeMode,
3809
+ poolState.tokenBAmount,
3810
+ poolState.liquidity
3749
3811
  );
3812
+ const singleSidedA = isSingleSidedA(poolState);
3813
+ const singleSidedB = isSingleSidedB(poolState);
3814
+ if (singleSidedA) {
3815
+ if (!jupiterQuoteToA) {
3816
+ throw new Error(
3817
+ "No Jupiter quote for token A found for single-sided pool, unable to proceed"
3818
+ );
3819
+ }
3820
+ const result = yield buildJupiterSwapTransaction(
3821
+ user,
3822
+ inputTokenMint,
3823
+ tokenAMint,
3824
+ amountIn,
3825
+ maxAccounts,
3826
+ slippageBps,
3827
+ void 0,
3828
+ {
3829
+ jupiterApiUrl: this.jupiterApiUrl,
3830
+ jupiterApiKey: this.jupiterApiKey
3831
+ }
3832
+ );
3833
+ return {
3834
+ user,
3835
+ pool,
3836
+ position,
3837
+ positionNftAccount,
3838
+ maxSqrtPriceChangeBps,
3839
+ amount: new import_anchor.BN(0),
3840
+ isDirectPool: false,
3841
+ tokenAMint,
3842
+ tokenBMint,
3843
+ tokenAVault,
3844
+ tokenBVault,
3845
+ tokenAProgram,
3846
+ tokenBProgram,
3847
+ maxTransferAmountA: getExtendMaxAmountTransfer(
3848
+ result.quoteResponse.outAmount,
3849
+ maxTransferAmountExtendPercentage
3850
+ ),
3851
+ swapType: 0 /* swapToA */,
3852
+ maxTransferAmountB: new import_anchor.BN(0),
3853
+ preSqrtPrice: poolState.sqrtPrice,
3854
+ preInstructions,
3855
+ swapTransactions: [result.transaction],
3856
+ cleanUpInstructions,
3857
+ swapInEstimate: {
3858
+ inAmountA: amountIn,
3859
+ inAmountB: new import_anchor.BN(0),
3860
+ routeA: "jupiter" /* Jupiter */,
3861
+ routeB: "dammV2" /* DammV2 */
3862
+ }
3863
+ };
3864
+ }
3865
+ if (singleSidedB) {
3866
+ if (!jupiterQuoteToB) {
3867
+ throw new Error(
3868
+ "No Jupiter quote for token B found for single-sided pool, unable to proceed"
3869
+ );
3870
+ }
3871
+ const result = yield buildJupiterSwapTransaction(
3872
+ user,
3873
+ inputTokenMint,
3874
+ tokenBMint,
3875
+ amountIn,
3876
+ maxAccounts,
3877
+ slippageBps,
3878
+ void 0,
3879
+ {
3880
+ jupiterApiUrl: this.jupiterApiUrl,
3881
+ jupiterApiKey: this.jupiterApiKey
3882
+ }
3883
+ );
3884
+ return {
3885
+ user,
3886
+ pool,
3887
+ position,
3888
+ positionNftAccount,
3889
+ maxSqrtPriceChangeBps,
3890
+ amount: new import_anchor.BN(0),
3891
+ isDirectPool: false,
3892
+ tokenAMint,
3893
+ tokenBMint,
3894
+ tokenAVault,
3895
+ tokenBVault,
3896
+ tokenAProgram,
3897
+ tokenBProgram,
3898
+ maxTransferAmountA: new import_anchor.BN(0),
3899
+ maxTransferAmountB: getExtendMaxAmountTransfer(
3900
+ result.quoteResponse.outAmount,
3901
+ maxTransferAmountExtendPercentage
3902
+ ),
3903
+ swapType: 1 /* swapToB */,
3904
+ preSqrtPrice: poolState.sqrtPrice,
3905
+ preInstructions,
3906
+ swapTransactions: [result.transaction],
3907
+ cleanUpInstructions,
3908
+ swapInEstimate: {
3909
+ inAmountA: new import_anchor.BN(0),
3910
+ inAmountB: amountIn,
3911
+ routeA: "dammV2" /* DammV2 */,
3912
+ routeB: "jupiter" /* Jupiter */
3913
+ }
3914
+ };
3915
+ }
3750
3916
  if (jupiterQuoteToA && jupiterQuoteToB === null) {
3751
- const { transaction: swapTransaction } = yield buildJupiterSwapTransaction(
3917
+ const result = yield buildJupiterSwapTransaction(
3752
3918
  user,
3753
3919
  inputTokenMint,
3754
3920
  tokenAMint,
@@ -3776,14 +3942,14 @@ var Zap = class {
3776
3942
  tokenAProgram,
3777
3943
  tokenBProgram,
3778
3944
  maxTransferAmountA: getExtendMaxAmountTransfer(
3779
- jupiterQuoteToA.outAmount,
3945
+ result.quoteResponse.outAmount,
3780
3946
  maxTransferAmountExtendPercentage
3781
3947
  ),
3782
3948
  swapType: 0 /* swapToA */,
3783
3949
  maxTransferAmountB: new import_anchor.BN(0),
3784
3950
  preSqrtPrice: poolState.sqrtPrice,
3785
3951
  preInstructions,
3786
- swapTransactions: [swapTransaction],
3952
+ swapTransactions: [result.transaction],
3787
3953
  cleanUpInstructions,
3788
3954
  swapInEstimate: {
3789
3955
  inAmountA: amountIn,
@@ -3794,7 +3960,7 @@ var Zap = class {
3794
3960
  };
3795
3961
  }
3796
3962
  if (jupiterQuoteToB && jupiterQuoteToA === null) {
3797
- const { transaction: swapTransaction } = yield buildJupiterSwapTransaction(
3963
+ const result = yield buildJupiterSwapTransaction(
3798
3964
  user,
3799
3965
  inputTokenMint,
3800
3966
  tokenBMint,
@@ -3823,13 +3989,13 @@ var Zap = class {
3823
3989
  tokenBProgram,
3824
3990
  maxTransferAmountA: new import_anchor.BN(0),
3825
3991
  maxTransferAmountB: getExtendMaxAmountTransfer(
3826
- jupiterQuoteToB.outAmount,
3992
+ result.quoteResponse.outAmount,
3827
3993
  maxTransferAmountExtendPercentage
3828
3994
  ),
3829
3995
  swapType: 1 /* swapToB */,
3830
3996
  preSqrtPrice: poolState.sqrtPrice,
3831
3997
  preInstructions,
3832
- swapTransactions: [swapTransaction],
3998
+ swapTransactions: [result.transaction],
3833
3999
  cleanUpInstructions,
3834
4000
  swapInEstimate: {
3835
4001
  inAmountA: new import_anchor.BN(0),
@@ -3863,6 +4029,24 @@ var Zap = class {
3863
4029
  )
3864
4030
  );
3865
4031
  const swapAmountToB = amountIn.sub(swapAmountToA);
4032
+ const baseParams = {
4033
+ user,
4034
+ pool,
4035
+ position,
4036
+ positionNftAccount,
4037
+ maxSqrtPriceChangeBps,
4038
+ amount: new import_anchor.BN(0),
4039
+ isDirectPool: false,
4040
+ tokenAMint,
4041
+ tokenBMint,
4042
+ tokenAVault,
4043
+ tokenBVault,
4044
+ tokenAProgram,
4045
+ tokenBProgram,
4046
+ preInstructions,
4047
+ preSqrtPrice: poolState.sqrtPrice,
4048
+ cleanUpInstructions
4049
+ };
3866
4050
  const { transaction: swapToATransaction, quoteResponse: swapToAQuote } = yield buildJupiterSwapTransaction(
3867
4051
  user,
3868
4052
  inputTokenMint,
@@ -3889,21 +4073,7 @@ var Zap = class {
3889
4073
  jupiterApiKey: this.jupiterApiKey
3890
4074
  }
3891
4075
  );
3892
- return {
3893
- user,
3894
- pool,
3895
- position,
3896
- positionNftAccount,
3897
- maxSqrtPriceChangeBps,
3898
- amount: new import_anchor.BN(0),
3899
- isDirectPool: false,
3900
- tokenAMint,
3901
- tokenBMint,
3902
- tokenAVault,
3903
- tokenBVault,
3904
- tokenAProgram,
3905
- tokenBProgram,
3906
- preInstructions,
4076
+ return __spreadProps(__spreadValues({}, baseParams), {
3907
4077
  maxTransferAmountA: getExtendMaxAmountTransfer(
3908
4078
  swapToAQuote.outAmount,
3909
4079
  maxTransferAmountExtendPercentage
@@ -3913,16 +4083,14 @@ var Zap = class {
3913
4083
  maxTransferAmountExtendPercentage
3914
4084
  ),
3915
4085
  swapType: 2 /* swapToBoth */,
3916
- preSqrtPrice: poolState.sqrtPrice,
3917
4086
  swapTransactions: [swapToATransaction, swapToBTransaction],
3918
- cleanUpInstructions,
3919
4087
  swapInEstimate: {
3920
4088
  inAmountA: swapAmountToA,
3921
4089
  inAmountB: swapAmountToB,
3922
4090
  routeA: "jupiter" /* Jupiter */,
3923
4091
  routeB: "jupiter" /* Jupiter */
3924
4092
  }
3925
- };
4093
+ });
3926
4094
  }
3927
4095
  throw new Error(
3928
4096
  "No Jupiter quote found for both tokens, unable to proceed"
@@ -4000,9 +4168,7 @@ var Zap = class {
4000
4168
  setupTransaction.add(...preInstructions);
4001
4169
  }
4002
4170
  const ledgerTransaction = new import_web38.Transaction();
4003
- const resetOrInitializeLedgerTx = yield this.resetOrInitializeLedgerAccount(
4004
- user
4005
- );
4171
+ const resetOrInitializeLedgerTx = yield this.resetOrInitializeLedgerAccount(user);
4006
4172
  ledgerTransaction.add(resetOrInitializeLedgerTx);
4007
4173
  if (isDirectPool) {
4008
4174
  const isTokenA = params.isTokenA;
@@ -4491,9 +4657,7 @@ var Zap = class {
4491
4657
  setupTransaction.add(...preInstructions);
4492
4658
  }
4493
4659
  const ledgerTransaction = new import_web38.Transaction();
4494
- const resetOrInitializeLedgerTx = yield this.resetOrInitializeLedgerAccount(
4495
- user
4496
- );
4660
+ const resetOrInitializeLedgerTx = yield this.resetOrInitializeLedgerAccount(user);
4497
4661
  ledgerTransaction.add(resetOrInitializeLedgerTx);
4498
4662
  if (isDirectRoute) {
4499
4663
  const { isTokenX, amount, maxTransferAmount } = params;
@@ -4796,9 +4960,7 @@ var Zap = class {
4796
4960
  const tokenXAmountAfterSwap = directSwapEstimate.swapType === 0 /* XToY */ ? tokenXAmount.sub(directSwapEstimate.swapAmount) : directSwapEstimate.swapType === 1 /* YToX */ ? tokenXAmount.add(directSwapEstimate.expectedOutput) : tokenXAmount;
4797
4961
  const tokenYAmountAfterSwap = directSwapEstimate.swapType === 0 /* XToY */ ? tokenYAmount.add(directSwapEstimate.expectedOutput) : directSwapEstimate.swapType === 1 /* YToX */ ? tokenYAmount.sub(directSwapEstimate.swapAmount) : tokenYAmount;
4798
4962
  const ledgerAddress = deriveLedgerAccount(user);
4799
- const ledgerAccountInfo = yield this.connection.getAccountInfo(
4800
- ledgerAddress
4801
- );
4963
+ const ledgerAccountInfo = yield this.connection.getAccountInfo(ledgerAddress);
4802
4964
  const ledgerTransaction = new import_web38.Transaction();
4803
4965
  if (!ledgerAccountInfo) {
4804
4966
  const initLedgerTx = yield this.initializeLedgerAccount(user, user);
@@ -5262,6 +5424,8 @@ var Zap = class {
5262
5424
  getOrCreateATAInstruction,
5263
5425
  getTokenAccountBalance,
5264
5426
  getTokenProgramFromMint,
5427
+ isSingleSidedA,
5428
+ isSingleSidedB,
5265
5429
  toProgramStrategyType,
5266
5430
  unwrapSOLInstruction,
5267
5431
  wrapSOLInstruction