@kamino-finance/klend-sdk 5.14.2 → 5.14.4

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.
Files changed (67) hide show
  1. package/dist/classes/configItems.d.ts +166 -0
  2. package/dist/classes/configItems.d.ts.map +1 -0
  3. package/dist/classes/configItems.js +202 -0
  4. package/dist/classes/configItems.js.map +1 -0
  5. package/dist/classes/manager.d.ts +4 -7
  6. package/dist/classes/manager.d.ts.map +1 -1
  7. package/dist/classes/manager.js +35 -292
  8. package/dist/classes/manager.js.map +1 -1
  9. package/dist/classes/market.d.ts.map +1 -1
  10. package/dist/classes/market.js +1 -1
  11. package/dist/classes/market.js.map +1 -1
  12. package/dist/classes/reserve.d.ts +5 -14
  13. package/dist/classes/reserve.d.ts.map +1 -1
  14. package/dist/classes/reserve.js +88 -463
  15. package/dist/classes/reserve.js.map +1 -1
  16. package/dist/classes/utils.d.ts +1 -0
  17. package/dist/classes/utils.d.ts.map +1 -1
  18. package/dist/classes/utils.js +12 -0
  19. package/dist/classes/utils.js.map +1 -1
  20. package/dist/classes/vault.d.ts.map +1 -1
  21. package/dist/classes/vault.js +7 -0
  22. package/dist/classes/vault.js.map +1 -1
  23. package/dist/classes/vault_types.d.ts +1 -0
  24. package/dist/classes/vault_types.d.ts.map +1 -1
  25. package/dist/client_kamino_manager.d.ts.map +1 -1
  26. package/dist/client_kamino_manager.js +4 -1
  27. package/dist/client_kamino_manager.js.map +1 -1
  28. package/dist/lending_operations/repay_with_collateral_operations.d.ts +2 -1
  29. package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
  30. package/dist/lending_operations/repay_with_collateral_operations.js +13 -9
  31. package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
  32. package/dist/lending_operations/swap_collateral_operations.d.ts +1 -1
  33. package/dist/lending_operations/swap_collateral_operations.d.ts.map +1 -1
  34. package/dist/lending_operations/swap_collateral_operations.js +34 -30
  35. package/dist/lending_operations/swap_collateral_operations.js.map +1 -1
  36. package/dist/leverage/operations.d.ts +4 -4
  37. package/dist/leverage/operations.d.ts.map +1 -1
  38. package/dist/leverage/operations.js +91 -55
  39. package/dist/leverage/operations.js.map +1 -1
  40. package/dist/leverage/types.d.ts +8 -6
  41. package/dist/leverage/types.d.ts.map +1 -1
  42. package/dist/leverage/utils.d.ts.map +1 -1
  43. package/dist/leverage/utils.js +40 -19
  44. package/dist/leverage/utils.js.map +1 -1
  45. package/dist/utils/instruction.d.ts +3 -1
  46. package/dist/utils/instruction.d.ts.map +1 -1
  47. package/dist/utils/instruction.js +17 -1
  48. package/dist/utils/instruction.js.map +1 -1
  49. package/dist/utils/managerTypes.d.ts.map +1 -1
  50. package/dist/utils/managerTypes.js +9 -3
  51. package/dist/utils/managerTypes.js.map +1 -1
  52. package/package.json +1 -1
  53. package/src/classes/configItems.ts +295 -0
  54. package/src/classes/manager.ts +47 -392
  55. package/src/classes/market.ts +6 -1
  56. package/src/classes/reserve.ts +115 -783
  57. package/src/classes/utils.ts +12 -0
  58. package/src/classes/vault.ts +15 -1
  59. package/src/classes/vault_types.ts +1 -0
  60. package/src/client_kamino_manager.ts +5 -1
  61. package/src/lending_operations/repay_with_collateral_operations.ts +34 -26
  62. package/src/lending_operations/swap_collateral_operations.ts +43 -36
  63. package/src/leverage/operations.ts +175 -147
  64. package/src/leverage/types.ts +8 -6
  65. package/src/leverage/utils.ts +41 -20
  66. package/src/utils/instruction.ts +28 -0
  67. package/src/utils/managerTypes.ts +9 -3
@@ -287,6 +287,18 @@ export function orThrow(message: string): never {
287
287
  throw new Error(message);
288
288
  }
289
289
 
290
+ export function blobEquals(left: Uint8Array, right: Uint8Array): boolean {
291
+ if (left.length !== right.length) {
292
+ return false;
293
+ }
294
+ for (let i = 0; i < left.length; ++i) {
295
+ if (left[i] !== right[i]) {
296
+ return false;
297
+ }
298
+ }
299
+ return true;
300
+ }
301
+
290
302
  /**
291
303
  * Returns an integer {@link Decimal} nearest to the given one.
292
304
  *
@@ -11,7 +11,13 @@ import {
11
11
  SYSVAR_RENT_PUBKEY,
12
12
  TransactionInstruction,
13
13
  } from '@solana/web3.js';
14
- import { getAssociatedTokenAddressSync, NATIVE_MINT, TOKEN_PROGRAM_ID, unpackAccount } from '@solana/spl-token';
14
+ import {
15
+ createCloseAccountInstruction,
16
+ getAssociatedTokenAddressSync,
17
+ NATIVE_MINT,
18
+ TOKEN_PROGRAM_ID,
19
+ unpackAccount,
20
+ } from '@solana/spl-token';
15
21
  import {
16
22
  getAssociatedTokenAddress,
17
23
  getTransferWsolIxs,
@@ -1064,6 +1070,7 @@ export class KaminoVaultClient {
1064
1070
  const withdrawIxs: WithdrawIxs = {
1065
1071
  unstakeFromFarmIfNeededIxs: [],
1066
1072
  withdrawIxs: [],
1073
+ postWithdrawIxs: [],
1067
1074
  };
1068
1075
 
1069
1076
  const shareLamportsToWithdraw = collToLamportsDecimal(shareAmount, vaultState.sharesMintDecimals.toNumber());
@@ -1099,6 +1106,13 @@ export class KaminoVaultClient {
1099
1106
  withdrawIxs.withdrawIxs = withdrawFromVaultIxs;
1100
1107
  }
1101
1108
 
1109
+ // if the vault is for SOL return the ix to unwrap the SOL
1110
+ if (vaultState.tokenMint.equals(NATIVE_MINT)) {
1111
+ const userWsolAta = getAssociatedTokenAddress(NATIVE_MINT, user);
1112
+ const unwrapIx = createCloseAccountInstruction(userWsolAta, user, user, [], TOKEN_PROGRAM_ID);
1113
+ withdrawIxs.postWithdrawIxs.push(unwrapIx);
1114
+ }
1115
+
1102
1116
  return withdrawIxs;
1103
1117
  }
1104
1118
 
@@ -48,6 +48,7 @@ export type DepositIxs = {
48
48
  export type WithdrawIxs = {
49
49
  unstakeFromFarmIfNeededIxs: TransactionInstruction[];
50
50
  withdrawIxs: TransactionInstruction[];
51
+ postWithdrawIxs: TransactionInstruction[]; // wSOL ATA close ix
51
52
  };
52
53
 
53
54
  /** The shares an user has in a vault (staked and unstaked), in tokens */
@@ -895,7 +895,7 @@ async function main() {
895
895
  const withdrawSig = await processTxn(
896
896
  env.client,
897
897
  env.payer,
898
- [...withdrawIxs.unstakeFromFarmIfNeededIxs, ...withdrawIxs.withdrawIxs],
898
+ [...withdrawIxs.unstakeFromFarmIfNeededIxs, ...withdrawIxs.withdrawIxs, ...withdrawIxs.postWithdrawIxs],
899
899
  mode,
900
900
  2500,
901
901
  [],
@@ -1156,6 +1156,10 @@ async function main() {
1156
1156
  printHoldings(holdings);
1157
1157
  console.log(`Tokens per share for vault ${vaultAddress.toBase58()}: ${tokensPerShare}`);
1158
1158
  console.log('vaultOverview', vaultOverview);
1159
+
1160
+ for (const [reserveAddress, reserveOverview] of vaultOverview.reservesOverview) {
1161
+ console.log(`reserve ${reserveAddress.toBase58()} supplyAPY ${reserveOverview.supplyAPY}`);
1162
+ }
1159
1163
  });
1160
1164
 
1161
1165
  commands.command('get-oracle-mappings').action(async () => {
@@ -28,6 +28,7 @@ export type RepayWithCollIxsResponse<QuoteResponse> = {
28
28
  flashLoanInfo: FlashLoanInfo;
29
29
  swapInputs: SwapInputs;
30
30
  initialInputs: RepayWithCollInitialInputs<QuoteResponse>;
31
+ quote?: QuoteResponse;
31
32
  };
32
33
 
33
34
  export type RepayWithCollInitialInputs<QuoteResponse> = {
@@ -129,6 +130,7 @@ export async function getRepayWithCollSwapInputs<QuoteResponse>({
129
130
  preActionIxs: [],
130
131
  swapIxs: [],
131
132
  lookupTables: [],
133
+ quote: {} as SwapQuote<QuoteResponse>,
132
134
  },
133
135
  isClosingPosition,
134
136
  repayAmountLamports,
@@ -193,7 +195,7 @@ export async function getRepayWithCollIxs<QuoteResponse>({
193
195
  scopeRefreshConfig,
194
196
  useV2Ixs,
195
197
  logger = console.log,
196
- }: RepayWithCollIxsProps<QuoteResponse>): Promise<RepayWithCollIxsResponse<QuoteResponse>> {
198
+ }: RepayWithCollIxsProps<QuoteResponse>): Promise<Array<RepayWithCollIxsResponse<QuoteResponse>>> {
197
199
  const { swapInputs, initialInputs } = await getRepayWithCollSwapInputs({
198
200
  collTokenMint,
199
201
  currentSlot,
@@ -234,33 +236,39 @@ export async function getRepayWithCollIxs<QuoteResponse>({
234
236
  .div(actualSwapInLamports.div(collReserve.getMintFactor()))} ${debtReserve.symbol}/${collReserve.symbol}`
235
237
  );
236
238
 
237
- const swapResponse = await swapper(swapInputs, initialInputs.klendAccounts, swapQuote);
238
- const ixs: LeverageIxsOutput = await buildRepayWithCollateralIxs(
239
- kaminoMarket,
240
- debtReserve,
241
- collReserve,
242
- obligation,
243
- referrer,
244
- currentSlot,
245
- budgetAndPriorityFeeIxs,
246
- scopeRefreshConfig,
247
- swapResponse,
248
- isClosingPosition,
249
- debtRepayAmountLamports,
250
- swapInputs.inputAmountLamports,
251
- useV2Ixs
239
+ const swapResponses = await swapper(swapInputs, initialInputs.klendAccounts, swapQuote);
240
+
241
+ return Promise.all(
242
+ swapResponses.map(async (swapResponse) => {
243
+ const ixs: LeverageIxsOutput = await buildRepayWithCollateralIxs(
244
+ kaminoMarket,
245
+ debtReserve,
246
+ collReserve,
247
+ obligation,
248
+ referrer,
249
+ currentSlot,
250
+ budgetAndPriorityFeeIxs,
251
+ scopeRefreshConfig,
252
+ swapResponse,
253
+ isClosingPosition,
254
+ debtRepayAmountLamports,
255
+ swapInputs.inputAmountLamports,
256
+ useV2Ixs
257
+ );
258
+
259
+ return {
260
+ ixs: ixs.instructions,
261
+ lookupTables: swapResponse.lookupTables,
262
+ swapInputs,
263
+ flashLoanInfo: ixs.flashLoanInfo,
264
+ initialInputs,
265
+ quote: swapResponse.quote.quoteResponse,
266
+ };
267
+ })
252
268
  );
253
-
254
- return {
255
- ixs: ixs.instructions,
256
- lookupTables: swapResponse.lookupTables,
257
- swapInputs,
258
- flashLoanInfo: ixs.flashLoanInfo,
259
- initialInputs,
260
- };
261
269
  }
262
270
 
263
- async function buildRepayWithCollateralIxs(
271
+ async function buildRepayWithCollateralIxs<QuoteResponse>(
264
272
  market: KaminoMarket,
265
273
  debtReserve: KaminoReserve,
266
274
  collReserve: KaminoReserve,
@@ -269,7 +277,7 @@ async function buildRepayWithCollateralIxs(
269
277
  currentSlot: number,
270
278
  budgetAndPriorityFeeIxs: TransactionInstruction[] | undefined,
271
279
  scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
272
- swapQuoteIxs: SwapIxs,
280
+ swapQuoteIxs: SwapIxs<QuoteResponse>,
273
281
  isClosingPosition: boolean,
274
282
  debtRepayAmountLamports: Decimal,
275
283
  collWithdrawLamports: Decimal,
@@ -145,7 +145,7 @@ export interface SwapCollIxsOutputs<QuoteResponse> {
145
145
  */
146
146
  export async function getSwapCollIxs<QuoteResponse>(
147
147
  inputs: SwapCollIxsInputs<QuoteResponse>
148
- ): Promise<SwapCollIxsOutputs<QuoteResponse>> {
148
+ ): Promise<Array<SwapCollIxsOutputs<QuoteResponse>>> {
149
149
  const [args, context] = extractArgsAndContext(inputs);
150
150
 
151
151
  // Conceptually, we need to construct the following ixs:
@@ -165,33 +165,37 @@ export async function getSwapCollIxs<QuoteResponse>(
165
165
  const klendAccounts = uniqueAccountsWithProgramIds(listIxs(fakeKlendIxs));
166
166
 
167
167
  // Construct the external swap ixs (and learn the actual swap-out amount):
168
- const externalSwapIxs = await getExternalSwapIxs(args, klendAccounts, context);
168
+ const externalSwapIxsArray = await getExternalSwapIxs(args, klendAccounts, context);
169
169
 
170
- // We now have the full information needed to simulate the end-state, so let's check that the operation is legal:
171
- context.logger(
172
- `Expected to swap ${args.sourceCollSwapAmount} ${context.sourceCollReserve.symbol} collateral into ${externalSwapIxs.swapOutAmount} ${context.targetCollReserve.symbol} collateral`
170
+ return Promise.all(
171
+ externalSwapIxsArray.map(async (externalSwapIxs) => {
172
+ // We now have the full information needed to simulate the end-state, so let's check that the operation is legal:
173
+ context.logger(
174
+ `Expected to swap ${args.sourceCollSwapAmount} ${context.sourceCollReserve.symbol} collateral into ${externalSwapIxs.swapOutAmount} ${context.targetCollReserve.symbol} collateral`
175
+ );
176
+ checkResultingObligationValid(args, externalSwapIxs.swapOutAmount, context);
177
+
178
+ // Construct the Klend's own ixs with an actual swap-out amount:
179
+ const klendIxs = await getKlendIxs(args, externalSwapIxs.swapOutAmount, context);
180
+
181
+ return {
182
+ ixs: listIxs(klendIxs, externalSwapIxs.ixs),
183
+ lookupTables: externalSwapIxs.luts,
184
+ useV2Ixs: context.useV2Ixs,
185
+ simulationDetails: {
186
+ flashLoan: {
187
+ targetCollFlashBorrowedAmount: klendIxs.simulationDetails.targetCollFlashBorrowedAmount,
188
+ targetCollFlashRepaidAmount: externalSwapIxs.swapOutAmount,
189
+ },
190
+ externalSwap: {
191
+ sourceCollSwapInAmount: args.sourceCollSwapAmount, // repeated `/inputs.sourceCollSwapAmount`, only for clarity
192
+ targetCollSwapOutAmount: externalSwapIxs.swapOutAmount, // repeated `../flashLoan.targetCollFlashRepaidAmount`, only for clarity
193
+ quoteResponse: externalSwapIxs.simulationDetails.quoteResponse,
194
+ },
195
+ },
196
+ };
197
+ })
173
198
  );
174
- checkResultingObligationValid(args, externalSwapIxs.swapOutAmount, context);
175
-
176
- // Construct the Klend's own ixs with an actual swap-out amount:
177
- const klendIxs = await getKlendIxs(args, externalSwapIxs.swapOutAmount, context);
178
-
179
- return {
180
- ixs: listIxs(klendIxs, externalSwapIxs.ixs),
181
- lookupTables: externalSwapIxs.luts,
182
- useV2Ixs: context.useV2Ixs,
183
- simulationDetails: {
184
- flashLoan: {
185
- targetCollFlashBorrowedAmount: klendIxs.simulationDetails.targetCollFlashBorrowedAmount,
186
- targetCollFlashRepaidAmount: externalSwapIxs.swapOutAmount,
187
- },
188
- externalSwap: {
189
- sourceCollSwapInAmount: args.sourceCollSwapAmount, // repeated `/inputs.sourceCollSwapAmount`, only for clarity
190
- targetCollSwapOutAmount: externalSwapIxs.swapOutAmount, // repeated `../flashLoan.targetCollFlashRepaidAmount`, only for clarity
191
- quoteResponse: externalSwapIxs.simulationDetails.quoteResponse,
192
- },
193
- },
194
- };
195
199
  }
196
200
 
197
201
  type SwapCollArgs = {
@@ -508,7 +512,7 @@ async function getExternalSwapIxs<QuoteResponse>(
508
512
  args: SwapCollArgs,
509
513
  klendAccounts: PublicKey[],
510
514
  context: SwapCollContext<QuoteResponse>
511
- ): Promise<ExternalSwapIxs<QuoteResponse>> {
515
+ ): Promise<Array<ExternalSwapIxs<QuoteResponse>>> {
512
516
  const externalSwapInputs = {
513
517
  inputAmountLamports: args.sourceCollSwapAmount.mul(context.sourceCollReserve.getMintFactor()),
514
518
  inputMint: context.sourceCollReserve.getLiquidityMint(),
@@ -516,17 +520,20 @@ async function getExternalSwapIxs<QuoteResponse>(
516
520
  amountDebtAtaBalance: undefined, // only used for kTokens
517
521
  };
518
522
  const externalSwapQuote = await context.quoter(externalSwapInputs, klendAccounts);
519
- const swapOutAmount = externalSwapQuote.priceAInB.mul(args.sourceCollSwapAmount);
520
523
  const externalSwapIxsAndLuts = await context.swapper(externalSwapInputs, klendAccounts, externalSwapQuote);
524
+
521
525
  // Note: we can ignore the returned `preActionIxs` field - we do not request any of them from the swapper.
522
- return {
523
- swapOutAmount,
524
- ixs: externalSwapIxsAndLuts.swapIxs,
525
- luts: externalSwapIxsAndLuts.lookupTables,
526
- simulationDetails: {
527
- quoteResponse: externalSwapQuote.quoteResponse,
528
- },
529
- };
526
+ return externalSwapIxsAndLuts.map((externalSwapIxsAndLuts) => {
527
+ const swapOutAmount = externalSwapIxsAndLuts.quote.priceAInB.mul(args.sourceCollSwapAmount);
528
+ return {
529
+ swapOutAmount,
530
+ ixs: externalSwapIxsAndLuts.swapIxs,
531
+ luts: externalSwapIxsAndLuts.lookupTables,
532
+ simulationDetails: {
533
+ quoteResponse: externalSwapIxsAndLuts.quote.quoteResponse,
534
+ },
535
+ };
536
+ });
530
537
  }
531
538
 
532
539
  function checkResultingObligationValid(