@carrot-protocol/clend-rpc 0.1.26-p-withdraw-dev-e12dfc4 → 0.1.27-group-refactor1-dev-5488543

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/rpc.js CHANGED
@@ -12,13 +12,12 @@ const utils_1 = require("./utils");
12
12
  const addresses_1 = require("./addresses");
13
13
  const state_1 = require("./state");
14
14
  const clend_common_1 = require("@carrot-protocol/clend-common");
15
- const jupiterUtils_1 = require("./jupiterUtils");
16
- const api_1 = require("@jup-ag/api");
15
+ const swapper_1 = require("./swapper");
17
16
  const pyth_solana_receiver_1 = require("@pythnetwork/pyth-solana-receiver");
18
17
  const events_1 = require("./events");
19
18
  const marginfi_1 = require("./integrations/marginfi");
20
19
  class ClendClient {
21
- constructor(connection, wallet, skipPreflight, cuFeeInMicroLamports, jupiterUtils, dryRun, mintOracleMapping) {
20
+ constructor(connection, wallet, skipPreflight, cuFeeInMicroLamports, defaultSwapper, dryRun, mintOracleMapping) {
22
21
  this.provider = new anchor_1.AnchorProvider(connection, wallet, {
23
22
  commitment: "processed",
24
23
  skipPreflight,
@@ -26,7 +25,7 @@ class ClendClient {
26
25
  this.connection = connection;
27
26
  this.instructions = new instructions_1.Instructions(this.provider);
28
27
  this.events = new events_1.ClendEvents(connection);
29
- this.jupiterUtils = jupiterUtils || new jupiterUtils_1.JupiterUtils();
28
+ this.swapper = defaultSwapper || new swapper_1.JupiterSwapper();
30
29
  this.dryRun = dryRun || false;
31
30
  this.cuFeeInMicroLamports = cuFeeInMicroLamports;
32
31
  this.mintOracleMapping = mintOracleMapping || state_1.DEFAULT_ORACLE_MAP;
@@ -34,16 +33,25 @@ class ClendClient {
34
33
  address() {
35
34
  return this.provider.wallet.publicKey;
36
35
  }
37
- /**
38
- * Get Jupiter price for a token pair
39
- */
40
- async getJupiterPrice(mint) {
41
- return this.jupiterUtils.getJupiterPrice(mint);
36
+ // determine type of oracle then fetch price from mint
37
+ // TODO: do it better than this hack
38
+ async getOraclePrice(mint) {
39
+ try {
40
+ return await this.getPythOraclePrice(mint);
41
+ }
42
+ catch (e) {
43
+ try {
44
+ return await this.getSBOraclePrice(mint);
45
+ }
46
+ catch (sbError) {
47
+ throw sbError;
48
+ }
49
+ }
42
50
  }
43
51
  /**
44
52
  * Get pyth oracle price for a token
45
53
  */
46
- async getOraclePrice(mint) {
54
+ async getPythOraclePrice(mint) {
47
55
  const oracle = this.getOracle(mint);
48
56
  // get oracle account info
49
57
  const oracleAccountInfo = await this.connection.getAccountInfo(oracle, {
@@ -62,9 +70,34 @@ class ClendClient {
62
70
  // get ema price
63
71
  const emaPrice = new anchor_1.BN(oracleData.priceMessage.emaPrice);
64
72
  // return price
65
- return (emaPrice.toNumber() *
66
- Math.pow(10, Number(oracleData.priceMessage.exponent)));
73
+ return (0, utils_1.calculatePriceUi)(emaPrice.toNumber(), oracleData.priceMessage.exponent);
67
74
  }
75
+ async getSBOraclePrice(mint) {
76
+ const oracle = this.getOracle(mint);
77
+ // Fetch the raw account info.
78
+ const feedAccountInfo = await this.connection.getAccountInfo(oracle, "processed");
79
+ if (feedAccountInfo === null) {
80
+ throw new Error(`Feed account ${oracle.toString()} not found.`);
81
+ }
82
+ // Use our manual parser instead of the Anchor coder.
83
+ const pullFeedAccountData = (0, utils_1.parsePullFeedAccountData)(feedAccountInfo.data);
84
+ if (!pullFeedAccountData ||
85
+ !pullFeedAccountData.submissions ||
86
+ pullFeedAccountData.submissions.length === 0) {
87
+ throw new Error(`No valid submissions found for feed ${oracle.toString()}.`);
88
+ }
89
+ // The latest submission will be the first element after sorting.
90
+ const latestSubmission = pullFeedAccountData.submissions[0];
91
+ // The 'value' is a BN (BigNumber), so we convert it to a standard JavaScript number.
92
+ // Be aware of potential precision loss if the number is larger than Number.MAX_SAFE_INTEGER.
93
+ const price = new decimal_js_1.default(latestSubmission.value.toString());
94
+ // The exponent for Switchboard v2/v3 feeds is typically -18, but you should
95
+ // confirm this for the specific feed you are using.
96
+ const exponent = -18;
97
+ const priceDecimal = (0, utils_1.calculatePriceUiDecimal)(price, exponent);
98
+ return priceDecimal;
99
+ }
100
+ // find oracle for a mint from in memory cache
68
101
  getOracle(mint) {
69
102
  const oracleStr = this.mintOracleMapping.get(mint.toString());
70
103
  if (!oracleStr) {
@@ -72,18 +105,6 @@ class ClendClient {
72
105
  }
73
106
  return new anchor_1.web3.PublicKey(oracleStr);
74
107
  }
75
- /**
76
- * Get Jupiter quote for a swap
77
- */
78
- async getJupiterQuote(inputMint, outputMint, inputMintDecimals, outputMintDecimals, inputAmountLamports, slippageBps, swapMode) {
79
- return this.jupiterUtils.getJupiterQuote(inputMint, outputMint, inputMintDecimals, outputMintDecimals, inputAmountLamports, slippageBps, swapMode);
80
- }
81
- /**
82
- * Get Jupiter swap instructions
83
- */
84
- async getJupiterSwap(payer, inputs, quote) {
85
- return this.jupiterUtils.getJupiterSwap(payer, inputs, quote);
86
- }
87
108
  async send(ixns, additionalSigners = [], additionalLuts = []) {
88
109
  const cuPriorityFeeIx = anchor_1.web3.ComputeBudgetProgram.setComputeUnitPrice({
89
110
  microLamports: this.cuFeeInMicroLamports,
@@ -176,11 +197,11 @@ class ClendClient {
176
197
  return this.send([initIx]);
177
198
  }
178
199
  // Bank Operations
179
- async addBank(clendGroup, bankMint, pythOracle, pythOracleFeedId, bankConfig, interestRateConfig) {
200
+ async addBank(clendGroup, bankMint, oracleSetupArgs, bankConfig, interestRateConfig) {
180
201
  const tokenProgram = (0, utils_1.getTokenProgramForMint)(bankMint);
181
202
  const feeStateAccountData = await this.getFeeState();
182
203
  const globalFeeWallet = feeStateAccountData.globalFeeWallet;
183
- const { bank, ixns } = await this.instructions.addBank(clendGroup, this.address(), globalFeeWallet, bankMint, tokenProgram, pythOracle, pythOracleFeedId, bankConfig, interestRateConfig);
204
+ const { bank, ixns } = await this.instructions.addBank(clendGroup, this.address(), globalFeeWallet, bankMint, tokenProgram, oracleSetupArgs, bankConfig, interestRateConfig);
184
205
  const txSig = await this.send(ixns);
185
206
  return { bank, txSig };
186
207
  }
@@ -511,9 +532,10 @@ class ClendClient {
511
532
  const ix = await this.instructions.resetBankFees(bankData.group, this.address(), bank);
512
533
  return this.send([ix]);
513
534
  }
514
- async liquidateClendAccountWithFlashLoan(liquidatorClendAccount, liquidateeClendAccount, assetBankData, liabBankData, targetOnChainMaintenanceHealthValue, slippageBps, marginfiLiabFlashLoanBank, liquidatorMarginfiAccount, additionalIxnCount) {
535
+ async liquidateClendAccountWithFlashLoan(liquidatorClendAccount, liquidateeClendAccount, assetBankData, liabBankData, targetOnChainMaintenanceHealthValue, slippageBps, marginfiLiabFlashLoanBank, liquidatorMarginfiAccount, additionalIxnCount, // used to calculate the end flash loan index
536
+ swapperOverride) {
515
537
  // create instructions
516
- const result = await this.getLiquidateClendAccountIxns(liquidatorClendAccount, liquidateeClendAccount, assetBankData, liabBankData, targetOnChainMaintenanceHealthValue, slippageBps);
538
+ const result = await this.getLiquidateClendAccountIxns(liquidatorClendAccount, liquidateeClendAccount, assetBankData, liabBankData, targetOnChainMaintenanceHealthValue, slippageBps, swapperOverride);
517
539
  if (!result) {
518
540
  return;
519
541
  }
@@ -546,8 +568,8 @@ class ClendClient {
546
568
  ];
547
569
  return this.send(ixns, [], luts);
548
570
  }
549
- async liquidateClendAccount(liquidatorClendAccount, liquidateeClendAccount, assetBankData, liabBankData, targetOnChainMaintenanceHealthValue, slippageBps) {
550
- const result = await this.getLiquidateClendAccountIxns(liquidatorClendAccount, liquidateeClendAccount, assetBankData, liabBankData, targetOnChainMaintenanceHealthValue, slippageBps);
571
+ async liquidateClendAccount(liquidatorClendAccount, liquidateeClendAccount, assetBankData, liabBankData, targetOnChainMaintenanceHealthValue, slippageBps, swapperOverride) {
572
+ const result = await this.getLiquidateClendAccountIxns(liquidatorClendAccount, liquidateeClendAccount, assetBankData, liabBankData, targetOnChainMaintenanceHealthValue, slippageBps, swapperOverride);
551
573
  if (!result) {
552
574
  return;
553
575
  }
@@ -572,7 +594,12 @@ class ClendClient {
572
594
  * Must be <= 0.
573
595
  * returns: instructions, luts, deposit amount (libaility token)
574
596
  */
575
- async getLiquidateClendAccountIxns(liquidatorClendAccount, liquidateeClendAccount, assetBankData, liabBankData, targetOnChainMaintenanceHealthValue, slippageBps) {
597
+ async getLiquidateClendAccountIxns(liquidatorClendAccount, liquidateeClendAccount, assetBankData, liabBankData, targetOnChainMaintenanceHealthValue, slippageBps, swapperOverride) {
598
+ let activeSwapper = this.swapper;
599
+ // override swapper if provided
600
+ if (swapperOverride) {
601
+ activeSwapper = swapperOverride;
602
+ }
576
603
  utils_1.logger.info("Starting liquidation calculation", {
577
604
  liquidatee: liquidateeClendAccount.authority.toString(),
578
605
  liquidator: liquidatorClendAccount.authority.toString(),
@@ -691,30 +718,32 @@ class ClendClient {
691
718
  // just withdraw the liquidated amount
692
719
  // balance for the asset
693
720
  const withdrawAssetIx = await this.instructions.withdraw(assetBankData.group, liquidatorClendAccount.key, liquidatorClendAccount.authority, assetBankData.key, liquidatorAssetAta, assetTokenProgram, finalAssetAmount, false, remainingAccounts);
694
- // create jupiter swap asset for debt
695
- const swapQuote = await this.getJupiterQuote(assetBankData.mint, liabBankData.mint, assetBankData.mintDecimals, liabBankData.mintDecimals, new decimal_js_1.default(finalAssetAmount.toString()), // Swap asset received from liquidation
696
- slippageBps, api_1.SwapMode.ExactIn);
697
- const outAmountMin = new anchor_1.BN(swapQuote.quoteResponse.otherAmountThreshold);
721
+ // get a swap quote
722
+ const swapQuote = await activeSwapper.getQuote({
723
+ payer: liquidatorClendAccount.authority,
724
+ inputMint: assetBankData.mint,
725
+ inputMintDecimals: assetBankData.mintDecimals,
726
+ outputMint: liabBankData.mint,
727
+ outputMintDecimals: liabBankData.mintDecimals,
728
+ inputAmount: finalAssetAmount,
729
+ slippageBps,
730
+ swapMode: "ExactIn",
731
+ });
732
+ const outAmountMin = swapQuote.otherAmountThreshold;
698
733
  utils_1.logger.debug("liquidateClendAccount: Jupiter swapQuote for total amount", {
699
- inAmount: swapQuote.quoteResponse.inAmount,
700
- outAmount: swapQuote.quoteResponse.outAmount,
734
+ inAmount: swapQuote.inAmount.toString(10),
735
+ outAmount: swapQuote.outAmount.toString(10),
701
736
  outAmountMin: outAmountMin.toString(10),
702
- priceImpactPct: swapQuote.quoteResponse.priceImpactPct,
703
737
  });
704
738
  // 5. Get Swap Instructions from Jupiter
705
- const swapInputs = {
706
- inputAmountLamports: new decimal_js_1.default(finalAssetAmount.toString()),
707
- inputMint: assetBankData.mint,
708
- outputMint: liabBankData.mint,
709
- };
710
- const jupiterSwapIxs = await this.getJupiterSwap(this.address(), swapInputs, swapQuote);
739
+ const swapIxns = await activeSwapper.getSwapIxns(swapQuote);
711
740
  const ixns = [
712
741
  depositIx, // deposit liability mint into liquidator clend account
713
742
  liquidationIx, // liquidate liquidatee clend account
714
743
  withdrawAssetIx, // withdraw liquidated asset from liquidator clend account
715
- ...jupiterSwapIxs.swapIxs, // swap liquidated asset for liability mint
744
+ ...swapIxns.ixns, // swap liquidated asset for liability mint
716
745
  ];
717
- return { ixns, luts: jupiterSwapIxs.lookupTables, depositAmount };
746
+ return { ixns, luts: swapIxns.luts, depositAmount };
718
747
  }
719
748
  async configureBankInterestRate(bank, interestRateConfig) {
720
749
  const bankData = await this.getBank(bank);
@@ -748,28 +777,28 @@ class ClendClient {
748
777
  }
749
778
  async configureBankOracle(bank, pythOracle, pythOracleFeed) {
750
779
  const bankData = await this.getBank(bank);
751
- const ix = await this.instructions.configureBankOracle(bankData.group, this.address(), bank, pythOracle, pythOracleFeed);
780
+ const ix = await this.instructions.configureBankPythOracle(bankData.group, this.address(), bank, pythOracle, pythOracleFeed);
752
781
  return this.send([ix]);
753
782
  }
754
783
  async setBankOperationalState(clendGroup, bank, operationalState) {
755
784
  const ix = await this.instructions.setBankOperationalState(clendGroup, this.address(), bank, operationalState);
756
785
  return this.send([ix]);
757
786
  }
758
- async depositLeverage(clendGroup, clendAccount, selectedMint, collateralMint, debtMint, depositAmount, targetLeverage, slippageBps) {
787
+ async depositLeverage(clendGroup, clendAccount, selectedMint, collateralMint, debtMint, depositAmount, targetLeverage, slippageBps, swapperOverride) {
759
788
  let ixns = [];
760
789
  let luts = [];
761
790
  let additionalSigners = [];
762
791
  switch (selectedMint.toString()) {
763
792
  case collateralMint.toString():
764
793
  const collateralParams = await this.getDepositLeverageFromCollateralParams(clendGroup, collateralMint, debtMint, depositAmount, targetLeverage, slippageBps);
765
- const { ixns: collateralIxns, luts: collateralLuts, additionalSigners: collateralAdditionalSigners, } = await this.getDepositLeverageFromCollateralIxns(clendGroup, this.address(), clendAccount, collateralMint, debtMint, collateralParams.collateralBankData.mintDecimals, collateralParams.debtBankData.mintDecimals, collateralParams.borrowAmount, depositAmount, slippageBps, 0);
794
+ const { ixns: collateralIxns, luts: collateralLuts, additionalSigners: collateralAdditionalSigners, } = await this.getDepositLeverageFromCollateralIxns(clendGroup, this.address(), clendAccount, collateralMint, debtMint, collateralParams.collateralBankData.mintDecimals, collateralParams.debtBankData.mintDecimals, collateralParams.borrowAmount, depositAmount, slippageBps, 0, swapperOverride);
766
795
  ixns = collateralIxns;
767
796
  luts = collateralLuts;
768
797
  additionalSigners = collateralAdditionalSigners;
769
798
  break;
770
799
  case debtMint.toString():
771
- const debtParams = await this.getDepositLeverageFromDebtParams(clendGroup, collateralMint, debtMint, depositAmount, targetLeverage, slippageBps);
772
- const { ixns: debtIxns, luts: debtLuts, additionalSigners: debtAdditionalSigners, } = await this.getDepositLeverageFromDebtIxns(clendGroup, this.address(), clendAccount, collateralMint, debtMint, debtParams.debtBankData.mintDecimals, debtParams.collateralBankData.mintDecimals, depositAmount, debtParams.borrowAmount, slippageBps, 0);
800
+ const debtParams = await this.getDepositLeverageFromDebtParams(clendGroup, collateralMint, debtMint, depositAmount, targetLeverage, slippageBps, swapperOverride);
801
+ const { ixns: debtIxns, luts: debtLuts, additionalSigners: debtAdditionalSigners, } = await this.getDepositLeverageFromDebtIxns(clendGroup, this.address(), clendAccount, collateralMint, debtMint, debtParams.debtBankData.mintDecimals, debtParams.collateralBankData.mintDecimals, depositAmount, debtParams.borrowAmount, slippageBps, 0, swapperOverride);
773
802
  ixns = debtIxns;
774
803
  luts = debtLuts;
775
804
  additionalSigners = debtAdditionalSigners;
@@ -781,7 +810,13 @@ class ClendClient {
781
810
  }
782
811
  async getDepositLeverageFromDebtIxns(clendGroup, user, clendAccount, collateralMint, // e.g., JLP
783
812
  debtMint, // e.g., USDC
784
- debtMintDecimals, collateralMintDecimals, initialUserDebtContributionForSwap, finalLoopBorrowAmount, slippageBps, additionalIxnCount) {
813
+ debtMintDecimals, collateralMintDecimals, initialUserDebtContributionForSwap, finalLoopBorrowAmount, slippageBps, additionalIxnCount, // For JIT liquidity, etc.
814
+ swapperOverride) {
815
+ // override swapper if provided
816
+ let activeSwapper = this.swapper;
817
+ if (swapperOverride) {
818
+ activeSwapper = swapperOverride;
819
+ }
785
820
  const collateralTokenProgram = (0, utils_1.getTokenProgramForMint)(collateralMint);
786
821
  const debtTokenProgram = (0, utils_1.getTokenProgramForMint)(debtMint);
787
822
  const debtBank = (0, addresses_1.getBankPda)(clendGroup, debtMint);
@@ -820,31 +855,31 @@ class ClendClient {
820
855
  // 2. Calculate Total Debt Token for Swap
821
856
  const totalDebtTokenForSwap = initialUserDebtContributionForSwap.add(finalLoopBorrowAmount);
822
857
  // 3. Get Jupiter Quote for the TOTAL debt token amount
823
- const swapMode = api_1.SwapMode.ExactIn;
824
- const swapQuote = await this.getJupiterQuote(debtMint, // Input: Total Debt Token (USDC)
825
- collateralMint, // Output: Collateral Token (JLP)
826
- debtMintDecimals, collateralMintDecimals, new decimal_js_1.default(totalDebtTokenForSwap.toString()), // Swap the combined amount
827
- slippageBps, swapMode);
858
+ const swapMode = "ExactIn";
859
+ const swapQuote = await activeSwapper.getQuote({
860
+ payer: user,
861
+ inputMint: debtMint,
862
+ inputMintDecimals: debtMintDecimals,
863
+ outputMint: collateralMint,
864
+ outputMintDecimals: collateralMintDecimals,
865
+ inputAmount: totalDebtTokenForSwap,
866
+ slippageBps,
867
+ swapMode,
868
+ });
828
869
  utils_1.logger.debug("getDepositLeverageFromDebtIxns: Jupiter swapQuote for total amount", {
829
- inAmount: swapQuote.quoteResponse.inAmount, // Should match totalDebtTokenForSwap
830
- outAmount: swapQuote.quoteResponse.outAmount, // This is the gross JLP output
831
- otherAmountThreshold: swapQuote.quoteResponse.otherAmountThreshold, // Min JLP
832
- priceImpactPct: swapQuote.quoteResponse.priceImpactPct,
870
+ inAmount: swapQuote.inAmount, // Should match totalDebtTokenForSwap
871
+ outAmount: swapQuote.outAmount, // This is the gross JLP output
872
+ otherAmountThreshold: swapQuote.otherAmountThreshold, // Min JLP
833
873
  });
834
874
  // Ensure the expectedCollateralOutAmount (passed in) is consistent with the quote's minimum
835
875
  // This serves as a sanity check; the instruction should use the quote's threshold.
836
876
  // deposit up to amount == true as well
837
- const optimisticCollateralFromQuote = new anchor_1.BN(swapQuote.quoteResponse.outAmount);
877
+ const optimisticCollateralFromQuote = new anchor_1.BN(swapQuote.outAmount);
838
878
  // 4. Get User ATAs
839
879
  const userDebtAta = (0, spl_token_1.getAssociatedTokenAddressSync)(debtMint, user, true, debtTokenProgram);
840
880
  const userCollateralAta = (0, spl_token_1.getAssociatedTokenAddressSync)(collateralMint, user, true, collateralTokenProgram);
841
881
  // 5. Get Swap Instructions from Jupiter
842
- const swapInputs = {
843
- inputAmountLamports: new decimal_js_1.default(totalDebtTokenForSwap.toString()),
844
- inputMint: debtMint,
845
- outputMint: collateralMint,
846
- };
847
- const jupiterSwapIxs = await this.getJupiterSwap(user, swapInputs, swapQuote);
882
+ const swapIxns = await activeSwapper.getSwapIxns(swapQuote);
848
883
  // 6. Create Clend Protocol Instructions
849
884
  const borrowIx = await this.instructions.borrow(clendGroup, clendAccount, // clendAccount is guaranteed to be non-null here
850
885
  user, debtBank, userDebtAta, // Borrow into user's ATA
@@ -858,7 +893,7 @@ class ClendClient {
858
893
  // Order: Borrow additional debt, then swap combined debt, then deposit resulting collateral
859
894
  const ixnsWithoutFlashLoan = [
860
895
  borrowIx,
861
- ...jupiterSwapIxs.swapIxs,
896
+ ...swapIxns.ixns,
862
897
  depositIx,
863
898
  ];
864
899
  // 8. Wrap in Flash Loan
@@ -883,21 +918,41 @@ class ClendClient {
883
918
  ...ixnsWithoutFlashLoan,
884
919
  endFlashLoanIx,
885
920
  ];
886
- return { ixns, luts: jupiterSwapIxs.lookupTables, additionalSigners };
921
+ return {
922
+ clendAccount,
923
+ ixns,
924
+ luts: swapIxns.luts,
925
+ additionalSigners,
926
+ };
887
927
  }
888
- async getDepositLeverageFromCollateralIxns(clendGroup, user, clendAccount, collateralMint, debtMint, debtMintDecimals, collateralMintDecimals, borrowAmount, depositAmount, slippageBps, additionalIxnCount) {
928
+ async getDepositLeverageFromCollateralIxns(clendGroup, user, clendAccount, collateralMint, debtMint, debtMintDecimals, collateralMintDecimals, borrowAmount, depositAmount, slippageBps, additionalIxnCount, // used to correctly offset the flash loan index
929
+ swapperOverride) {
930
+ // override swapper if provided
931
+ let activeSwapper = this.swapper;
932
+ if (swapperOverride) {
933
+ activeSwapper = swapperOverride;
934
+ }
889
935
  // Get token programs
890
936
  const collateralTokenProgram = (0, utils_1.getTokenProgramForMint)(collateralMint);
891
937
  const debtTokenProgram = (0, utils_1.getTokenProgramForMint)(debtMint);
892
938
  const debtBank = (0, addresses_1.getBankPda)(clendGroup, debtMint);
893
939
  const collateralBank = (0, addresses_1.getBankPda)(clendGroup, collateralMint);
894
940
  // Get Jupiter quote for swapping debt token to collateral token
895
- const swapMode = api_1.SwapMode.ExactIn;
896
- const swapQuote = await this.getJupiterQuote(debtMint, collateralMint, debtMintDecimals, collateralMintDecimals, new decimal_js_1.default(borrowAmount.toString()), slippageBps, swapMode);
941
+ const swapMode = "ExactIn";
942
+ const swapQuote = await activeSwapper.getQuote({
943
+ payer: user,
944
+ inputMint: debtMint,
945
+ inputMintDecimals: debtMintDecimals,
946
+ outputMint: collateralMint,
947
+ outputMintDecimals: collateralMintDecimals,
948
+ inputAmount: borrowAmount,
949
+ slippageBps,
950
+ swapMode,
951
+ });
897
952
  utils_1.logger.debug("depositLeverage swapQuote", {
898
- inAmount: swapQuote.quoteResponse.inAmount,
899
- outAmount: swapQuote.quoteResponse.outAmount,
900
- priceImpactPct: swapQuote.quoteResponse.priceImpactPct,
953
+ inAmount: swapQuote.inAmount.toString(10),
954
+ outAmount: swapQuote.outAmount.toString(10),
955
+ otherAmountThreshold: swapQuote.otherAmountThreshold.toString(10),
901
956
  });
902
957
  let activeBanks = [];
903
958
  const additionalSigners = [];
@@ -936,14 +991,9 @@ class ClendClient {
936
991
  }
937
992
  const remainingAccounts = (0, utils_1.getClendAccountRemainingAccounts)(activeBankData);
938
993
  // Get swap instructions
939
- const swapInputs = {
940
- inputAmountLamports: new decimal_js_1.default(borrowAmount.toString()),
941
- inputMint: debtMint,
942
- outputMint: collateralMint,
943
- };
944
- const swapIxs = await this.getJupiterSwap(user, swapInputs, swapQuote);
994
+ const swapIxns = await activeSwapper.getSwapIxns(swapQuote);
945
995
  // Calculate additional collateral from swap
946
- const additionalCollateralAmount = new anchor_1.BN(swapQuote.quoteResponse.outAmount);
996
+ const additionalCollateralAmount = swapQuote.outAmount;
947
997
  const totalCollateralAmount = depositAmount.add(additionalCollateralAmount);
948
998
  const userDebtAta = (0, spl_token_1.getAssociatedTokenAddressSync)(debtMint, user, true, debtTokenProgram);
949
999
  const userCollateralAta = (0, spl_token_1.getAssociatedTokenAddressSync)(collateralMint, user, true, collateralTokenProgram);
@@ -955,7 +1005,7 @@ class ClendClient {
955
1005
  // add lending and swap instructions
956
1006
  const ixnsWithoutFlashLoan = [
957
1007
  borrowIx,
958
- ...swapIxs.swapIxs,
1008
+ ...swapIxns.ixns,
959
1009
  depositIx,
960
1010
  ];
961
1011
  // If the clend account is being created, we need to add 1 to the endIndex
@@ -979,7 +1029,12 @@ class ClendClient {
979
1029
  ...ixnsWithoutFlashLoan,
980
1030
  endFlashLoanIx,
981
1031
  ];
982
- return { ixns, luts: swapIxs.lookupTables, additionalSigners };
1032
+ return {
1033
+ clendAccount,
1034
+ ixns,
1035
+ luts: swapIxns.luts,
1036
+ additionalSigners,
1037
+ };
983
1038
  }
984
1039
  async getDepositLeverageFromCollateralParams(clendGroup, collateralMint, debtMint, depositAmount, targetLeverage, slippageBps) {
985
1040
  // Get decimals
@@ -1052,7 +1107,12 @@ class ClendClient {
1052
1107
  async getDepositLeverageFromDebtParams(clendGroup, collateralMint, // The asset being leveraged (e.g., JLP)
1053
1108
  debtMint, // The asset provided initially by the user (e.g., USDC)
1054
1109
  initialUserDebtContributionForSwap, // User's initial DEBT token for the swap
1055
- targetLeverage, slippageBps) {
1110
+ targetLeverage, slippageBps, swapperOverride) {
1111
+ // override swapper if provided
1112
+ let activeSwapper = this.swapper;
1113
+ if (swapperOverride) {
1114
+ activeSwapper = swapperOverride;
1115
+ }
1056
1116
  // 1. Get decimals and bank data
1057
1117
  const collateralDecimals = (0, utils_1.getTokenDecimalsForMint)(collateralMint);
1058
1118
  const debtDecimals = (0, utils_1.getTokenDecimalsForMint)(debtMint);
@@ -1083,12 +1143,18 @@ class ClendClient {
1083
1143
  // This is the user's initial contribution + what's borrowed from the protocol
1084
1144
  const totalDebtTokenForSwap = initialUserDebtContributionForSwap.add(finalLoopBorrowAmount);
1085
1145
  // 7. Calculate Expected COLLATERAL Output from swapping the total DEBT token amount
1086
- const swapQuote = await this.getJupiterQuote(debtMint, // Input: Total DEBT token (user's initial + borrowed from loop)
1087
- collateralMint, // Output: COLLATERAL token
1088
- debtDecimals, collateralDecimals, new decimal_js_1.default(totalDebtTokenForSwap.toString()), // Use the sum for the swap
1089
- slippageBps, api_1.SwapMode.ExactIn);
1146
+ const swapQuote = await activeSwapper.getQuote({
1147
+ payer: anchor_1.web3.PublicKey.default, // doesnt matter right now
1148
+ inputMint: debtMint,
1149
+ inputMintDecimals: debtDecimals,
1150
+ outputMint: collateralMint,
1151
+ outputMintDecimals: collateralDecimals,
1152
+ inputAmount: totalDebtTokenForSwap,
1153
+ slippageBps,
1154
+ swapMode: "ExactIn",
1155
+ });
1090
1156
  // Use the minimum amount threshold from the quote for safety in the final deposit instruction
1091
- const expectedCollateralOutAmount = new anchor_1.BN(swapQuote.quoteResponse.otherAmountThreshold);
1157
+ const expectedCollateralOutAmount = new anchor_1.BN(swapQuote.otherAmountThreshold);
1092
1158
  // --- Logging ---
1093
1159
  const finalLoopBorrowAmountUi = (0, clend_common_1.amountToUi)(finalLoopBorrowAmount, debtDecimals);
1094
1160
  const totalDebtTokenForSwapUi = (0, clend_common_1.amountToUi)(totalDebtTokenForSwap, debtDecimals);
@@ -1117,19 +1183,19 @@ class ClendClient {
1117
1183
  collateralBankData,
1118
1184
  };
1119
1185
  }
1120
- async withdrawLeverage(clendGroup, clendAccount, selectedMint, collateralMint, debtMint, withdrawAmount, withdrawAll, slippageBps) {
1186
+ async withdrawLeverage(clendGroup, clendAccount, selectedMint, collateralMint, debtMint, withdrawAmount, withdrawAll, slippageBps, swapperOverride) {
1121
1187
  let ixns = [];
1122
1188
  let luts = [];
1123
1189
  switch (selectedMint.toString()) {
1124
1190
  case collateralMint.toString():
1125
- const collateralParams = await this.getNetWithdrawLeverageCollateralParams(clendGroup, clendAccount, collateralMint, debtMint, withdrawAmount, withdrawAll, slippageBps);
1126
- const { ixns: collateralIxns, luts: collateralLuts } = await this.getWithdrawLeverageCollateralIxns(clendGroup, clendAccount, collateralMint, debtMint, collateralParams.collateralBankData.mintDecimals, collateralParams.debtBankData.mintDecimals, withdrawAll, collateralParams.debtToRepay, collateralParams.collateralToWithdraw, slippageBps, 0);
1191
+ const collateralParams = await this.getNetWithdrawLeverageCollateralParams(clendGroup, clendAccount, collateralMint, debtMint, withdrawAmount, withdrawAll, slippageBps, swapperOverride);
1192
+ const { ixns: collateralIxns, luts: collateralLuts } = await this.getWithdrawLeverageCollateralIxns(clendGroup, clendAccount, collateralMint, debtMint, collateralParams.collateralBankData.mintDecimals, collateralParams.debtBankData.mintDecimals, withdrawAll, collateralParams.debtToRepay, collateralParams.collateralToWithdraw, slippageBps, 0, swapperOverride);
1127
1193
  ixns = collateralIxns;
1128
1194
  luts = collateralLuts;
1129
1195
  break;
1130
1196
  case debtMint.toString():
1131
- const debtParams = await this.getNetWithdrawLeverageDebtParams(clendGroup, clendAccount, collateralMint, debtMint, withdrawAmount, withdrawAll, slippageBps);
1132
- const { ixns: debtIxns, luts: debtLuts } = await this.getWithdrawLeverageDebtIxns(clendGroup, clendAccount, collateralMint, debtMint, debtParams.collateralBankData.mintDecimals, debtParams.debtBankData.mintDecimals, withdrawAll, debtParams.debtToRepay, debtParams.collateralToWithdraw, withdrawAmount, slippageBps, 0);
1197
+ const debtParams = await this.getNetWithdrawLeverageDebtParams(clendGroup, clendAccount, collateralMint, debtMint, withdrawAmount, withdrawAll, slippageBps, swapperOverride);
1198
+ const { ixns: debtIxns, luts: debtLuts } = await this.getWithdrawLeverageDebtIxns(clendGroup, clendAccount, collateralMint, debtMint, debtParams.collateralBankData.mintDecimals, debtParams.debtBankData.mintDecimals, withdrawAll, debtParams.debtToRepay, debtParams.collateralToWithdraw, withdrawAmount, slippageBps, 0, swapperOverride);
1133
1199
  ixns = debtIxns;
1134
1200
  luts = debtLuts;
1135
1201
  break;
@@ -1139,7 +1205,12 @@ class ClendClient {
1139
1205
  // Send transaction
1140
1206
  return this.send(ixns, [], luts);
1141
1207
  }
1142
- async getWithdrawLeverageCollateralIxns(clendGroup, clendAccount, collateralMint, debtMint, collateralDecimals, debtDecimals, withdrawAll, debtToRepay, collateralToWithdraw, slippageBps, additionalIxnCount) {
1208
+ async getWithdrawLeverageCollateralIxns(clendGroup, clendAccount, collateralMint, debtMint, collateralDecimals, debtDecimals, withdrawAll, debtToRepay, collateralToWithdraw, slippageBps, additionalIxnCount, swapperOverride) {
1209
+ // override swapper if provided
1210
+ let activeSwapper = this.swapper;
1211
+ if (swapperOverride) {
1212
+ activeSwapper = swapperOverride;
1213
+ }
1143
1214
  const debtBank = (0, addresses_1.getBankPda)(clendGroup, debtMint);
1144
1215
  const collateralBank = (0, addresses_1.getBankPda)(clendGroup, collateralMint);
1145
1216
  // Get remaining accounts for flash loan
@@ -1155,10 +1226,19 @@ class ClendClient {
1155
1226
  }
1156
1227
  const remainingAccounts = (0, utils_1.getClendAccountRemainingAccounts)(activeBankData);
1157
1228
  // Get Jupiter quote for swapping collateral to debt token (ExactOut mode)
1158
- const swapMode = api_1.SwapMode.ExactOut;
1159
- const swapQuote = await this.getJupiterQuote(collateralMint, debtMint, collateralDecimals, debtDecimals, new decimal_js_1.default(debtToRepay.toString()), slippageBps, swapMode);
1229
+ const swapMode = "ExactOut";
1230
+ const swapQuote = await activeSwapper.getQuote({
1231
+ payer: clendAccountData.authority,
1232
+ inputMint: collateralMint,
1233
+ inputMintDecimals: collateralDecimals,
1234
+ outputMint: debtMint,
1235
+ outputMintDecimals: debtDecimals,
1236
+ inputAmount: debtToRepay,
1237
+ slippageBps,
1238
+ swapMode,
1239
+ });
1160
1240
  // set collateralToSwap to the inAmount from the swap quote
1161
- const collateralToSwap = swapQuote.quoteResponse.inAmount;
1241
+ const collateralToSwap = swapQuote.inAmount;
1162
1242
  utils_1.logger.debug("withdrawLeverage collateralToSwap", {
1163
1243
  collateralToSwap,
1164
1244
  });
@@ -1171,7 +1251,7 @@ class ClendClient {
1171
1251
  utils_1.logger.debug("withdrawLeverage swapInputs", {
1172
1252
  swapInputs,
1173
1253
  });
1174
- const swapIxs = await this.getJupiterSwap(clendAccountData.authority, swapInputs, swapQuote);
1254
+ const swapIxns = await activeSwapper.getSwapIxns(swapQuote);
1175
1255
  utils_1.logger.info(`swapIxns fetched`);
1176
1256
  const collateralTokenProgram = (0, utils_1.getTokenProgramForMint)(collateralMint);
1177
1257
  const debtTokenProgram = (0, utils_1.getTokenProgramForMint)(debtMint);
@@ -1187,7 +1267,7 @@ class ClendClient {
1187
1267
  // Assemble all instructions without flash loan
1188
1268
  const ixnsWithoutFlashLoan = [
1189
1269
  withdrawIx,
1190
- ...swapIxs.swapIxs,
1270
+ ...swapIxns.ixns,
1191
1271
  repayIx,
1192
1272
  ];
1193
1273
  utils_1.logger.info(`ixnsWithoutFlashLoan set`);
@@ -1201,9 +1281,14 @@ class ClendClient {
1201
1281
  ...ixnsWithoutFlashLoan,
1202
1282
  endFlashLoanIx,
1203
1283
  ];
1204
- return { ixns: instructions, luts: swapIxs.lookupTables };
1284
+ return { ixns: instructions, luts: swapIxns.luts };
1205
1285
  }
1206
- async getWithdrawLeverageDebtIxns(clendGroup, clendAccount, collateralMint, debtMint, collateralDecimals, debtDecimals, withdrawAll, debtToRepay, collateralToWithdraw, desiredNetDebtToReceive, slippageBps, additionalIxnCount) {
1286
+ async getWithdrawLeverageDebtIxns(clendGroup, clendAccount, collateralMint, debtMint, collateralDecimals, debtDecimals, withdrawAll, debtToRepay, collateralToWithdraw, desiredNetDebtToReceive, slippageBps, additionalIxnCount, swapperOverride) {
1287
+ // override swapper if provided
1288
+ let activeSwapper = this.swapper;
1289
+ if (swapperOverride) {
1290
+ activeSwapper = swapperOverride;
1291
+ }
1207
1292
  const debtBank = (0, addresses_1.getBankPda)(clendGroup, debtMint);
1208
1293
  const collateralBank = (0, addresses_1.getBankPda)(clendGroup, collateralMint);
1209
1294
  const clendAccountData = await this.getClendAccount(clendAccount);
@@ -1221,24 +1306,26 @@ class ClendClient {
1221
1306
  // 1. Determine Total USDC Needed from the Swap
1222
1307
  // This is the amount needed to repay Clend's debt AND give the user their desired net withdrawal.
1223
1308
  const totalDebtToReceive = debtToRepay.add(desiredNetDebtToReceive);
1224
- const swapMode = api_1.SwapMode.ExactIn;
1225
- const swapQuote = await this.getJupiterQuote(collateralMint, debtMint, collateralDecimals, debtDecimals, new decimal_js_1.default(collateralToWithdraw.toString()), // amount to swap
1226
- slippageBps, swapMode);
1227
- const minUsdcReceivedFromSwap_BN = new anchor_1.BN(swapQuote.quoteResponse.otherAmountThreshold);
1309
+ const swapMode = "ExactIn";
1310
+ const swapQuote = await activeSwapper.getQuote({
1311
+ payer: clendAccountData.authority,
1312
+ inputMint: collateralMint,
1313
+ inputMintDecimals: collateralDecimals,
1314
+ outputMint: debtMint,
1315
+ outputMintDecimals: debtDecimals,
1316
+ inputAmount: collateralToWithdraw,
1317
+ slippageBps,
1318
+ swapMode,
1319
+ });
1320
+ const minUsdcReceivedFromSwap_BN = new anchor_1.BN(swapQuote.otherAmountThreshold);
1228
1321
  utils_1.logger.debug("getWithdrawLeverageDebtIxns: collateral and debt details", {
1229
1322
  debtToRepay: debtToRepay.toString(),
1230
1323
  desiredNetDebtToReceive: desiredNetDebtToReceive.toString(),
1231
1324
  totalDebtToReceive: totalDebtToReceive.toString(),
1232
1325
  minUsdcReceivedFromSwap_BN: minUsdcReceivedFromSwap_BN.toString(),
1233
1326
  });
1234
- // 3. Get Swap Instructions from Jupiter
1235
- // The input for the swap is the total JLP we are withdrawing from Clend.
1236
- const swapInputs = {
1237
- inputAmountLamports: new decimal_js_1.default(collateralToWithdraw.toString()),
1238
- inputMint: collateralMint,
1239
- outputMint: debtMint,
1240
- };
1241
- const jupiterSwapIxs = await this.getJupiterSwap(clendAccountData.authority, swapInputs, swapQuote);
1327
+ // 3. Get Swap Instructions from swapper
1328
+ const swapIxns = await activeSwapper.getSwapIxns(swapQuote);
1242
1329
  utils_1.logger.info(`swapIxns fetched for ReceiveDebtToken`);
1243
1330
  // --- ATAs and Clend Instructions (largely similar structure) ---
1244
1331
  const collateralTokenProgram = (0, utils_1.getTokenProgramForMint)(collateralMint);
@@ -1256,9 +1343,9 @@ class ClendClient {
1256
1343
  // Assemble instructions
1257
1344
  const ixnsWithoutFlashLoan = [
1258
1345
  withdrawIx,
1259
- ...jupiterSwapIxs.swapIxs, // Swap all withdrawn JLP to USDC
1346
+ ...swapIxns.ixns, // Swap all withdrawn collateral to debt
1260
1347
  repayIx, // Repay the debt portion
1261
- ]; // User is left with the remaining USDC in their ATA
1348
+ ]; // User is left with the remaining debt in their ATA
1262
1349
  // Flash Loan Wrapping (same as before)
1263
1350
  const cuIxns = 2;
1264
1351
  const endIndex = new anchor_1.BN(cuIxns + ixnsWithoutFlashLoan.length + 1 + additionalIxnCount);
@@ -1268,11 +1355,16 @@ class ClendClient {
1268
1355
  ...ixnsWithoutFlashLoan,
1269
1356
  endFlashLoanIx,
1270
1357
  ];
1271
- return { ixns: instructions, luts: jupiterSwapIxs.lookupTables };
1358
+ return { ixns: instructions, luts: swapIxns.luts };
1272
1359
  }
1273
1360
  // caller will receive desiredNetWithdraw, the position will be adjusted accordingly
1274
1361
  // receive the collateral mint
1275
- async getNetWithdrawLeverageCollateralParams(clendGroup, clendAccount, collateralMint, debtMint, desiredNetWithdraw, withdrawAll, slippageBps) {
1362
+ async getNetWithdrawLeverageCollateralParams(clendGroup, clendAccount, collateralMint, debtMint, desiredNetWithdraw, withdrawAll, slippageBps, swapperOverride) {
1363
+ // override swapper if provided
1364
+ let activeSwapper = this.swapper;
1365
+ if (swapperOverride) {
1366
+ activeSwapper = swapperOverride;
1367
+ }
1276
1368
  utils_1.logger.info("getNetWithdrawParams", {
1277
1369
  desiredNetWithdraw: desiredNetWithdraw.toString(),
1278
1370
  withdrawAll,
@@ -1360,11 +1452,17 @@ class ClendClient {
1360
1452
  // --- Step 6: Get a Jupiter Quote for the Swap ---
1361
1453
  // Query Jupiter for an EXACT_OUT swap to find out exactly how much collateral
1362
1454
  // is needed to get the final amount of debt we need to repay.
1363
- const swapQuote = await this.getJupiterQuote(collateralMint, // From JLP
1364
- debtMint, // To USDC
1365
- collateralDecimals, debtDecimals, new decimal_js_1.default(debtToRepay.toString()), // We need this exact amount of USDC
1366
- slippageBps, api_1.SwapMode.ExactOut);
1367
- const collateralNeededForSwap = new anchor_1.BN(swapQuote.quoteResponse.inAmount);
1455
+ const swapQuote = await activeSwapper.getQuote({
1456
+ payer: clendAccountData.authority,
1457
+ inputMint: collateralMint,
1458
+ inputMintDecimals: collateralDecimals,
1459
+ outputMint: debtMint,
1460
+ outputMintDecimals: debtDecimals,
1461
+ inputAmount: debtToRepay,
1462
+ slippageBps,
1463
+ swapMode: "ExactOut",
1464
+ });
1465
+ const collateralNeededForSwap = new anchor_1.BN(swapQuote.inAmount);
1368
1466
  // --- Step 7: Calculate the Final Total Collateral to Withdraw ---
1369
1467
  // This is the sum of what the user gets (desiredNetWithdraw) and what the swap needs.
1370
1468
  collateralToWithdraw = desiredNetWithdraw.add(collateralNeededForSwap);
@@ -1386,7 +1484,12 @@ class ClendClient {
1386
1484
  }
1387
1485
  // caller will receive desiredNetWithdraw, the position will be adjusted accordingly
1388
1486
  // receive the debt mint
1389
- async getNetWithdrawLeverageDebtParams(clendGroup, clendAccount, collateralMint, debtMint, desiredNetWithdraw, withdrawAll, slippageBps) {
1487
+ async getNetWithdrawLeverageDebtParams(clendGroup, clendAccount, collateralMint, debtMint, desiredNetWithdraw, withdrawAll, slippageBps, swapperOverride) {
1488
+ // override swapper if provided
1489
+ let activeSwapper = this.swapper;
1490
+ if (swapperOverride) {
1491
+ activeSwapper = swapperOverride;
1492
+ }
1390
1493
  utils_1.logger.info("getNetWithdrawDebtParams", {
1391
1494
  desiredNetWithdraw: desiredNetWithdraw.toString(),
1392
1495
  withdrawAll,
@@ -1466,9 +1569,18 @@ class ClendClient {
1466
1569
  // The total value we need to get from selling JLP is the debt we must repay
1467
1570
  const totalDebtNeededFromSwap = debtToRepay.add(desiredNetWithdraw);
1468
1571
  // Now, find how much collateral is needed to produce this swap via swap
1469
- const swapQuote = await this.getJupiterQuote(collateralMint, debtMint, collateralDecimals, debtDecimals, new decimal_js_1.default(totalDebtNeededFromSwap.toString()), slippageBps, api_1.SwapMode.ExactOut);
1470
- // The answer from Jupiter is the total collateral we must withdraw.
1471
- collateralToWithdraw = new anchor_1.BN(swapQuote.quoteResponse.inAmount);
1572
+ const swapQuote = await activeSwapper.getQuote({
1573
+ payer: clendAccountData.authority,
1574
+ inputMint: collateralMint,
1575
+ inputMintDecimals: collateralDecimals,
1576
+ outputMint: debtMint,
1577
+ outputMintDecimals: debtDecimals,
1578
+ inputAmount: totalDebtNeededFromSwap,
1579
+ slippageBps,
1580
+ swapMode: "ExactOut",
1581
+ });
1582
+ // The answer from swapper is the total collateral we must withdraw.
1583
+ collateralToWithdraw = swapQuote.inAmount;
1472
1584
  // --- Step 4: Final Sanity Check ---
1473
1585
  if (collateralToWithdraw.gt(collateralAmount)) {
1474
1586
  throw new Error("Total required collateral for withdrawal and swap exceeds the available balance.");
@@ -1485,9 +1597,9 @@ class ClendClient {
1485
1597
  debtBankData,
1486
1598
  };
1487
1599
  }
1488
- async adjustLeverage(clendGroup, clendAccount, collateralMint, debtMint, targetLeverage, slippageBps) {
1600
+ async adjustLeverage(clendGroup, clendAccount, collateralMint, debtMint, targetLeverage, slippageBps, swapperOverride) {
1489
1601
  const params = await this.getAdjustLeverageParams(clendGroup, clendAccount, collateralMint, debtMint, targetLeverage, slippageBps);
1490
- const { ixns, luts } = await this.getAdjustLeverageIxns(clendGroup, clendAccount, this.address(), params.debtBankData, params.collateralBankData, params.isIncrease, params.finalDebtDeltaUi, params.finalCollateralDeltaUi, slippageBps, 0);
1602
+ const { ixns, luts } = await this.getAdjustLeverageIxns(clendGroup, clendAccount, this.address(), params.debtBankData, params.collateralBankData, params.isIncrease, params.finalDebtDeltaUi, params.finalCollateralDeltaUi, slippageBps, 0, swapperOverride);
1491
1603
  // Send transaction
1492
1604
  return this.send(ixns, [], luts);
1493
1605
  }
@@ -1695,7 +1807,12 @@ class ClendClient {
1695
1807
  */
1696
1808
  async getAdjustLeverageIxns(clendGroup, clendAccount, user, debtBankData, collateralBankData, isIncrease, finalDebtDeltaUi, // Use the final adjusted value from getAdjustLeverageParams
1697
1809
  finalCollateralDeltaUi, // Use the final adjusted value from getAdjustLeverageParams
1698
- slippageBps, additionalIxnCount) {
1810
+ slippageBps, additionalIxnCount, swapperOverride) {
1811
+ // override swapper if provided
1812
+ let activeSwapper = this.swapper;
1813
+ if (swapperOverride) {
1814
+ activeSwapper = swapperOverride;
1815
+ }
1699
1816
  const clendAccountData = await this.getClendAccount(clendAccount);
1700
1817
  if (!clendAccountData) {
1701
1818
  throw new Error(`Clend account not found: ${clendAccount.toString()}`);
@@ -1730,34 +1847,37 @@ class ClendClient {
1730
1847
  additionalDebtAmount: additionalDebtAmount.toString(),
1731
1848
  });
1732
1849
  // Get Jupiter quote for swapping debt token to collateral token (ExactIn)
1733
- const swapMode = api_1.SwapMode.ExactIn;
1734
- const swapQuote = await this.getJupiterQuote(debtBankData.mint, collateralBankData.mint, debtBankData.mintDecimals, collateralBankData.mintDecimals, new decimal_js_1.default(additionalDebtAmount.toString()), // Input is the final amount to borrow
1735
- slippageBps, swapMode);
1850
+ const swapMode = "ExactIn";
1851
+ const swapQuote = await activeSwapper.getQuote({
1852
+ payer: user,
1853
+ inputMint: debtBankData.mint,
1854
+ inputMintDecimals: debtBankData.mintDecimals,
1855
+ outputMint: collateralBankData.mint,
1856
+ outputMintDecimals: collateralBankData.mintDecimals,
1857
+ inputAmount: additionalDebtAmount,
1858
+ slippageBps,
1859
+ swapMode,
1860
+ });
1736
1861
  utils_1.logger.debug("swapQuote calculated (Increase)", {
1737
- inAmount: swapQuote.quoteResponse.inAmount,
1738
- outAmount: swapQuote.quoteResponse.outAmount,
1739
- priceImpactPct: swapQuote.quoteResponse.priceImpactPct,
1862
+ inAmount: swapQuote.inAmount.toString(),
1863
+ outAmount: swapQuote.outAmount.toString(),
1864
+ otherAmountThreshold: swapQuote.otherAmountThreshold.toString(),
1740
1865
  });
1741
1866
  // Get swap instructions
1742
- const swapInputs = {
1743
- inputAmountLamports: new decimal_js_1.default(additionalDebtAmount.toString()),
1744
- inputMint: debtBankData.mint,
1745
- outputMint: collateralBankData.mint,
1746
- };
1747
- const swapIxs = await this.getJupiterSwap(user, swapInputs, swapQuote);
1867
+ const swapIxns = await activeSwapper.getSwapIxns(swapQuote);
1748
1868
  // Borrow the final adjusted debt amount
1749
1869
  const borrowIx = await this.instructions.borrow(clendGroup, clendAccount, user, debtBankData.key, userDebtAta, debtTokenProgram, additionalDebtAmount, // Use final adjusted amount
1750
1870
  remainingAccounts);
1751
1871
  // Calculate additional collateral expected from swap (based on quote)
1752
- const additionalCollateralAmount = new anchor_1.BN(swapQuote.quoteResponse.outAmount);
1872
+ const additionalCollateralAmount = swapQuote.outAmount;
1753
1873
  utils_1.logger.debug("additionalCollateralAmount expected from swap", {
1754
1874
  additionalCollateralAmount: additionalCollateralAmount.toString(),
1755
1875
  });
1756
1876
  // Deposit additional collateral received from swap
1757
1877
  const depositIx = await this.instructions.deposit(clendGroup, clendAccount, user, collateralBankData.key, userCollateralAta, collateralTokenProgram, additionalCollateralAmount, // Deposit what the swap provides
1758
1878
  true, remainingAccounts);
1759
- instructions.push(borrowIx, ...swapIxs.swapIxs, depositIx);
1760
- swapLookupTables = swapIxs.lookupTables;
1879
+ instructions.push(borrowIx, ...swapIxns.ixns, depositIx);
1880
+ swapLookupTables = swapIxns.luts;
1761
1881
  }
1762
1882
  else {
1763
1883
  // Decreasing Leverage
@@ -1772,22 +1892,24 @@ class ClendClient {
1772
1892
  });
1773
1893
  // Get Jupiter quote for swapping collateral token to debt token (ExactOut)
1774
1894
  // Target the final buffered debt repayment amount
1775
- const swapMode = api_1.SwapMode.ExactOut;
1776
- const swapQuote = await this.getJupiterQuote(collateralBankData.mint, debtBankData.mint, collateralBankData.mintDecimals, debtBankData.mintDecimals, new decimal_js_1.default(finalDebtToRepayBN.toString()), // Target output amount
1777
- slippageBps, swapMode);
1778
- const estimatedCollateralInput = swapQuote.quoteResponse.inAmount;
1895
+ const swapMode = "ExactOut";
1896
+ const swapQuote = await activeSwapper.getQuote({
1897
+ payer: clendAccountData.authority,
1898
+ inputMint: collateralBankData.mint,
1899
+ inputMintDecimals: collateralBankData.mintDecimals,
1900
+ outputMint: debtBankData.mint,
1901
+ outputMintDecimals: debtBankData.mintDecimals,
1902
+ inputAmount: finalDebtToRepayBN,
1903
+ slippageBps,
1904
+ swapMode,
1905
+ });
1906
+ const estimatedCollateralInput = swapQuote.inAmount;
1779
1907
  utils_1.logger.debug("swapQuote calculated (Decrease)", {
1780
1908
  targetOutput: finalDebtToRepayBN.toString(),
1781
1909
  estimatedInput: estimatedCollateralInput,
1782
1910
  maxInputCalculated: finalCollateralToWithdrawBN.toString(), // Compare Jupiter estimate vs our max calc
1783
- priceImpactPct: swapQuote.quoteResponse.priceImpactPct,
1784
1911
  });
1785
- const swapInputs = {
1786
- inputAmountLamports: new decimal_js_1.default(swapQuote.quoteResponse.inAmount.toString()),
1787
- inputMint: collateralBankData.mint,
1788
- outputMint: debtBankData.mint,
1789
- };
1790
- const swapIxs = await this.getJupiterSwap(user, swapInputs, swapQuote);
1912
+ const swapIxns = await activeSwapper.getSwapIxns(swapQuote);
1791
1913
  // Withdraw the CALCULATED MAXIMUM collateral needed (includes swap input + buffer)
1792
1914
  const withdrawIx = await this.instructions.withdraw(clendGroup, clendAccount, user, collateralBankData.key, userCollateralAta, collateralTokenProgram, finalCollateralToWithdrawBN, // Use the final adjusted amount from params
1793
1915
  false, // Not withdrawing all
@@ -1796,8 +1918,8 @@ class ClendClient {
1796
1918
  const repayIx = await this.instructions.repay(clendGroup, clendAccount, user, debtBankData.key, userDebtAta, debtTokenProgram, finalDebtToRepayBN, // Use the final adjusted amount from params
1797
1919
  false, // Not repaying all
1798
1920
  remainingAccounts);
1799
- instructions.push(withdrawIx, ...swapIxs.swapIxs, repayIx);
1800
- swapLookupTables = swapIxs.lookupTables;
1921
+ instructions.push(withdrawIx, ...swapIxns.ixns, repayIx);
1922
+ swapLookupTables = swapIxns.luts;
1801
1923
  }
1802
1924
  // --- Flash Loan Wrapping ---
1803
1925
  const cuIxns = 2; // Assuming 2 compute budget instructions are added later