@kamino-finance/klend-sdk 6.0.5-beta.0 → 6.0.5-beta.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.
Files changed (51) hide show
  1. package/dist/classes/action.d.ts +1 -1
  2. package/dist/classes/action.d.ts.map +1 -1
  3. package/dist/classes/action.js +32 -16
  4. package/dist/classes/action.js.map +1 -1
  5. package/dist/classes/manager.d.ts +29 -18
  6. package/dist/classes/manager.d.ts.map +1 -1
  7. package/dist/classes/manager.js +65 -47
  8. package/dist/classes/manager.js.map +1 -1
  9. package/dist/classes/market.d.ts +2 -3
  10. package/dist/classes/market.d.ts.map +1 -1
  11. package/dist/classes/market.js +27 -20
  12. package/dist/classes/market.js.map +1 -1
  13. package/dist/client_kamino_manager.d.ts.map +1 -1
  14. package/dist/client_kamino_manager.js +30 -22
  15. package/dist/client_kamino_manager.js.map +1 -1
  16. package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
  17. package/dist/lending_operations/repay_with_collateral_operations.js +36 -32
  18. package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
  19. package/dist/lending_operations/swap_collateral_operations.d.ts.map +1 -1
  20. package/dist/lending_operations/swap_collateral_operations.js +4 -4
  21. package/dist/lending_operations/swap_collateral_operations.js.map +1 -1
  22. package/dist/leverage/operations.d.ts +4 -3
  23. package/dist/leverage/operations.d.ts.map +1 -1
  24. package/dist/leverage/operations.js +186 -154
  25. package/dist/leverage/operations.js.map +1 -1
  26. package/dist/leverage/types.d.ts +1 -0
  27. package/dist/leverage/types.d.ts.map +1 -1
  28. package/dist/utils/managerTypes.d.ts +1 -2
  29. package/dist/utils/managerTypes.d.ts.map +1 -1
  30. package/dist/utils/managerTypes.js +9 -9
  31. package/dist/utils/managerTypes.js.map +1 -1
  32. package/dist/utils/oracle.d.ts +2 -2
  33. package/dist/utils/oracle.d.ts.map +1 -1
  34. package/dist/utils/oracle.js.map +1 -1
  35. package/dist/utils/pubkey.d.ts +1 -0
  36. package/dist/utils/pubkey.d.ts.map +1 -1
  37. package/dist/utils/pubkey.js +10 -0
  38. package/dist/utils/pubkey.js.map +1 -1
  39. package/package.json +2 -2
  40. package/src/classes/action.ts +32 -20
  41. package/src/classes/manager.ts +80 -51
  42. package/src/classes/market.ts +36 -29
  43. package/src/client.ts +4 -4
  44. package/src/client_kamino_manager.ts +40 -35
  45. package/src/lending_operations/repay_with_collateral_operations.ts +76 -72
  46. package/src/lending_operations/swap_collateral_operations.ts +13 -11
  47. package/src/leverage/operations.ts +362 -328
  48. package/src/leverage/types.ts +1 -0
  49. package/src/utils/managerTypes.ts +1 -2
  50. package/src/utils/oracle.ts +2 -2
  51. package/src/utils/pubkey.ts +9 -0
@@ -52,18 +52,18 @@ import {
52
52
  TokenInfo,
53
53
  WithdrawalCaps,
54
54
  } from './idl_codegen/types';
55
- import { Fraction } from './classes/fraction';
55
+ import { Fraction } from './classes';
56
56
  import Decimal from 'decimal.js';
57
57
  import { BN } from '@coral-xyz/anchor';
58
58
  import { PythConfiguration, SwitchboardConfiguration } from './idl_codegen_kamino_vault/types';
59
59
  import * as fs from 'fs';
60
- import { MarketWithAddress } from './utils/managerTypes';
60
+ import { MarketWithAddress } from './utils';
61
61
  import {
62
62
  ManagementFeeBps,
63
63
  PendingVaultAdmin,
64
64
  PerformanceFeeBps,
65
65
  } from './idl_codegen_kamino_vault/types/VaultConfigField';
66
- import { getAccountOwner } from './utils/rpc';
66
+ import { getAccountOwner } from './utils';
67
67
  import { getAssociatedTokenAddressSync } from '@solana/spl-token';
68
68
 
69
69
  dotenv.config({
@@ -157,12 +157,12 @@ async function main() {
157
157
 
158
158
  console.log('reserve: ', reserve.publicKey);
159
159
 
160
- const _createReserveSig = await processTxn(env.client, env.payer, txnIxs[0], mode, 2500, [reserve]);
160
+ await processTxn(env.client, env.payer, txnIxs[0], mode, 2500, [reserve]);
161
161
 
162
162
  const [lut, createLutIxs] = await createUpdateReserveConfigLutIxs(env, marketAddress, reserve.publicKey);
163
163
  await processTxn(env.client, env.payer, createLutIxs, mode, 2500, []);
164
164
 
165
- const _updateSig = await processTxn(env.client, env.payer, txnIxs[1], mode, 2500, [], 400_000, 1000, [lut]);
165
+ await processTxn(env.client, env.payer, txnIxs[1], mode, 2500, [], 400_000, 1000, [lut]);
166
166
 
167
167
  mode === 'execute' &&
168
168
  console.log(
@@ -224,7 +224,7 @@ async function main() {
224
224
  updateEntireConfig
225
225
  );
226
226
 
227
- const _updateReserveSig = await processTxn(env.client, env.payer, ixs, mode, 2500, [], 400_000);
227
+ await processTxn(env.client, env.payer, ixs, mode, 2500, [], 400_000);
228
228
 
229
229
  mode === 'execute' && console.log('Reserve Updated with config -> ', JSON.parse(JSON.stringify(reserveConfig)));
230
230
  });
@@ -296,7 +296,7 @@ async function main() {
296
296
 
297
297
  const { vault: vaultKp, initVaultIxs: instructions } = await kaminoManager.createVaultIxs(kaminoVaultConfig);
298
298
 
299
- const _createVaultSig = await processTxn(
299
+ await processTxn(
300
300
  env.client,
301
301
  env.payer,
302
302
  [...instructions.createAtaIfNeededIxs, ...instructions.initVaultIxs, instructions.createLUTIx],
@@ -305,7 +305,7 @@ async function main() {
305
305
  [vaultKp]
306
306
  );
307
307
  await sleep(2000);
308
- const _populateLUTSig = await processTxn(
308
+ await processTxn(
309
309
  env.client,
310
310
  env.payer,
311
311
  [...instructions.populateLUTIxs, ...instructions.cleanupIxs],
@@ -314,14 +314,7 @@ async function main() {
314
314
  []
315
315
  );
316
316
 
317
- const _setSharesMetadataSig = await processTxn(
318
- env.client,
319
- env.payer,
320
- [instructions.initSharesMetadataIx],
321
- mode,
322
- 2500,
323
- []
324
- );
317
+ await processTxn(env.client, env.payer, [instructions.initSharesMetadataIx], mode, 2500, []);
325
318
  mode === 'execute' && console.log('Vault created:', vaultKp.publicKey.toBase58());
326
319
  });
327
320
 
@@ -1173,19 +1166,33 @@ async function main() {
1173
1166
  }
1174
1167
  });
1175
1168
 
1176
- commands.command('get-oracle-mappings').action(async () => {
1177
- const env = initializeClient(false, false);
1178
- const kaminoManager = new KaminoManager(
1179
- env.connection,
1180
- DEFAULT_RECENT_SLOT_DURATION_MS,
1181
- env.kLendProgramId,
1182
- env.kVaultProgramId
1183
- );
1169
+ commands
1170
+ .command('get-oracle-mappings')
1171
+ .requiredOption('--lending-market <string>', 'Lending Market Address')
1172
+ .action(async ({ lendingMarket }) => {
1173
+ const env = initializeClient(false, false);
1174
+ const kaminoManager = new KaminoManager(
1175
+ env.connection,
1176
+ DEFAULT_RECENT_SLOT_DURATION_MS,
1177
+ env.kLendProgramId,
1178
+ env.kVaultProgramId
1179
+ );
1180
+ const market = await KaminoMarket.load(
1181
+ env.connection,
1182
+ new PublicKey(lendingMarket),
1183
+ DEFAULT_RECENT_SLOT_DURATION_MS,
1184
+ env.kLendProgramId
1185
+ );
1186
+ if (!market) {
1187
+ throw Error(`Lending market ${lendingMarket} not found`);
1188
+ }
1184
1189
 
1185
- console.log('Getting oracle mappings');
1186
- const oracleConfigs = await kaminoManager.getScopeOracleConfigs();
1187
- console.log('oracleConfigs', JSON.parse(JSON.stringify(oracleConfigs)));
1188
- });
1190
+ console.log('Getting oracle mappings');
1191
+ const oracleConfigs = await kaminoManager.getScopeOracleConfigs(market);
1192
+ for (const [oraclePrices, configs] of oracleConfigs.entries()) {
1193
+ console.log(`OraclePrices pubkey: ${oraclePrices.toString()}`, 'Configs:', JSON.parse(JSON.stringify(configs)));
1194
+ }
1195
+ });
1189
1196
 
1190
1197
  commands.command('get-all-vaults').action(async () => {
1191
1198
  const env = initializeClient(false, false);
@@ -1370,7 +1377,7 @@ async function main() {
1370
1377
  // executing 6 ixs in a txn to make sure they fit
1371
1378
  for (let ixnIndex = 0; ixnIndex < ixs.length; ixnIndex += 6) {
1372
1379
  const ixnToExecute = ixs.slice(ixnIndex, ixnIndex + 6);
1373
- const _updateLendingMarketSig = await processTxn(env.client, env.payer, ixnToExecute, mode, 2500, [], 400_000);
1380
+ await processTxn(env.client, env.payer, ixnToExecute, mode, 2500, [], 400_000);
1374
1381
  }
1375
1382
 
1376
1383
  mode === 'execute' &&
@@ -1410,7 +1417,7 @@ async function main() {
1410
1417
 
1411
1418
  const ix = kaminoManager.updateLendingMarketOwnerIxs(marketWithAddress);
1412
1419
 
1413
- const _updateLendingMarketSig = await processTxn(env.client, env.payer, [ix], mode, 2500, [], 400_000);
1420
+ await processTxn(env.client, env.payer, [ix], mode, 2500, [], 400_000);
1414
1421
 
1415
1422
  mode === 'execute' &&
1416
1423
  console.log(
@@ -1465,7 +1472,7 @@ async function main() {
1465
1472
 
1466
1473
  const ixs = kaminoManager.updateLendingMarketIxs(marketWithAddress, newLendingMarket);
1467
1474
 
1468
- const _updateLendingMarketSig = await processTxn(env.client, env.payer, ixs, mode, 2500, [], 400_000);
1475
+ await processTxn(env.client, env.payer, ixs, mode, 2500, [], 400_000);
1469
1476
 
1470
1477
  mode === 'execute' &&
1471
1478
  console.log(
@@ -1520,7 +1527,7 @@ async function main() {
1520
1527
 
1521
1528
  const ixs = await kaminoManager.updateReserveIxs(marketWithAddress, reserveAddress, newReserveConfig);
1522
1529
 
1523
- const _updateLendingMarketSig = await processTxn(env.client, env.payer, ixs, mode, 2500, [], 400_000);
1530
+ await processTxn(env.client, env.payer, ixs, mode, 2500, [], 400_000);
1524
1531
 
1525
1532
  mode === 'execute' &&
1526
1533
  console.log(
@@ -1811,9 +1818,7 @@ function parseBorrowRateCurve(reserveConfigFromFile: any): BorrowRateCurve {
1811
1818
 
1812
1819
  curvePoints.forEach((curvePoint, index) => (finalCurvePoints[index] = curvePoint));
1813
1820
 
1814
- const borrowRateCurve = new BorrowRateCurve({ points: finalCurvePoints });
1815
-
1816
- return borrowRateCurve;
1821
+ return new BorrowRateCurve({ points: finalCurvePoints });
1817
1822
  }
1818
1823
 
1819
1824
  function parseReserveBorrowLimitAgainstCollInEmode(reserveConfigFromFile: any): BN[] {
@@ -117,26 +117,30 @@ export async function getRepayWithCollSwapInputs<QuoteResponse>({
117
117
  const inputAmountLamports = Decimal.min(maxWithdrawableCollLamports, maxCollNeededFromOracle);
118
118
 
119
119
  // Build the repay & withdraw collateral tx to get the number of accounts
120
- const klendIxs: LeverageIxsOutput = await buildRepayWithCollateralIxs(
121
- kaminoMarket,
122
- debtReserve,
123
- collReserve,
124
- obligation,
125
- referrer,
126
- currentSlot,
127
- budgetAndPriorityFeeIxs,
128
- scopeRefreshConfig,
129
- {
130
- preActionIxs: [],
131
- swapIxs: [],
132
- lookupTables: [],
133
- quote: {} as SwapQuote<QuoteResponse>,
134
- },
135
- isClosingPosition,
136
- repayAmountLamports,
137
- inputAmountLamports,
138
- useV2Ixs
139
- );
120
+ const klendIxs: LeverageIxsOutput = (
121
+ await buildRepayWithCollateralIxs(
122
+ kaminoMarket,
123
+ debtReserve,
124
+ collReserve,
125
+ obligation,
126
+ referrer,
127
+ currentSlot,
128
+ budgetAndPriorityFeeIxs,
129
+ scopeRefreshConfig,
130
+ [
131
+ {
132
+ preActionIxs: [],
133
+ swapIxs: [],
134
+ lookupTables: [],
135
+ quote: {} as SwapQuote<QuoteResponse>,
136
+ },
137
+ ],
138
+ isClosingPosition,
139
+ repayAmountLamports,
140
+ inputAmountLamports,
141
+ useV2Ixs
142
+ )
143
+ )[0];
140
144
  const uniqueKlendAccounts = uniqueAccountsWithProgramIds(klendIxs.instructions);
141
145
 
142
146
  const swapQuoteInputs: SwapInputs = {
@@ -238,34 +242,32 @@ export async function getRepayWithCollIxs<QuoteResponse>({
238
242
 
239
243
  const swapResponses = await swapper(swapInputs, initialInputs.klendAccounts, swapQuote);
240
244
 
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
- })
245
+ const repayWithCollateralIxs = await buildRepayWithCollateralIxs(
246
+ kaminoMarket,
247
+ debtReserve,
248
+ collReserve,
249
+ obligation,
250
+ referrer,
251
+ currentSlot,
252
+ budgetAndPriorityFeeIxs,
253
+ scopeRefreshConfig,
254
+ swapResponses,
255
+ isClosingPosition,
256
+ debtRepayAmountLamports,
257
+ swapInputs.inputAmountLamports,
258
+ useV2Ixs
268
259
  );
260
+
261
+ return repayWithCollateralIxs.map((ixs, index) => {
262
+ return {
263
+ ixs: ixs.instructions,
264
+ lookupTables: swapResponses[index].lookupTables,
265
+ swapInputs,
266
+ flashLoanInfo: ixs.flashLoanInfo,
267
+ initialInputs,
268
+ quote: swapResponses[index].quote.quoteResponse,
269
+ };
270
+ });
269
271
  }
270
272
 
271
273
  async function buildRepayWithCollateralIxs<QuoteResponse>(
@@ -277,12 +279,12 @@ async function buildRepayWithCollateralIxs<QuoteResponse>(
277
279
  currentSlot: number,
278
280
  budgetAndPriorityFeeIxs: TransactionInstruction[] | undefined,
279
281
  scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
280
- swapQuoteIxs: SwapIxs<QuoteResponse>,
282
+ swapQuoteIxsArray: SwapIxs<QuoteResponse>[],
281
283
  isClosingPosition: boolean,
282
284
  debtRepayAmountLamports: Decimal,
283
285
  collWithdrawLamports: Decimal,
284
286
  useV2Ixs: boolean
285
- ): Promise<LeverageIxsOutput> {
287
+ ): Promise<LeverageIxsOutput[]> {
286
288
  // 1. Create atas & budget txns
287
289
  const budgetIxs = budgetAndPriorityFeeIxs || getComputeBudgetAndPriorityFeeIxs(1_400_000);
288
290
 
@@ -361,29 +363,31 @@ async function buildRepayWithCollateralIxs<QuoteResponse>(
361
363
  }
362
364
 
363
365
  // 4. Swap collateral to debt to repay flash loan
364
- const { preActionIxs, swapIxs } = swapQuoteIxs;
365
- const swapInstructions = removeBudgetIxs(swapIxs);
366
-
367
- const ixs = [
368
- ...scopeRefreshIxn,
369
- ...budgetIxs,
370
- ...atasAndIxs.map((x) => x.createAtaIx),
371
- flashBorrowIx,
372
- ...preActionIxs,
373
- ...KaminoAction.actionToIxs(repayAndWithdrawAction),
374
- ...swapInstructions,
375
- flashRepayIx,
376
- ];
377
-
378
- const res: LeverageIxsOutput = {
379
- flashLoanInfo: {
380
- flashBorrowReserve: debtReserve.address,
381
- flashLoanFee: debtReserve.getFlashLoanFee(),
382
- },
383
- instructions: ixs,
384
- };
385
-
386
- return res;
366
+ return swapQuoteIxsArray.map((swapQuoteIxs) => {
367
+ const { preActionIxs, swapIxs } = swapQuoteIxs;
368
+ const swapInstructions = removeBudgetIxs(swapIxs);
369
+
370
+ const ixs = [
371
+ ...scopeRefreshIxn,
372
+ ...budgetIxs,
373
+ ...atasAndIxs.map((x) => x.createAtaIx),
374
+ flashBorrowIx,
375
+ ...preActionIxs,
376
+ ...KaminoAction.actionToIxs(repayAndWithdrawAction),
377
+ ...swapInstructions,
378
+ flashRepayIx,
379
+ ];
380
+
381
+ const res: LeverageIxsOutput = {
382
+ flashLoanInfo: {
383
+ flashBorrowReserve: debtReserve.address,
384
+ flashLoanFee: debtReserve.getFlashLoanFee(),
385
+ },
386
+ instructions: ixs,
387
+ };
388
+
389
+ return res;
390
+ });
387
391
  }
388
392
 
389
393
  export const getMaxWithdrawLtvCheck = (
@@ -161,7 +161,16 @@ export async function getSwapCollIxs<QuoteResponse>(
161
161
  // - To construct 1. (i.e. flash-borrow), we need to know the target collateral swap-out from 4.
162
162
 
163
163
  // Construct the Klend's own ixs with a fake swap-out (only to learn the klend accounts used):
164
- const fakeKlendIxs = await getKlendIxs(args, FAKE_TARGET_COLL_SWAP_OUT_AMOUNT, context);
164
+
165
+ const scopeRefreshIxn = await getScopeRefreshIx(
166
+ context.market,
167
+ context.sourceCollReserve,
168
+ context.targetCollReserve,
169
+ context.obligation,
170
+ context.scopeRefreshConfig
171
+ );
172
+
173
+ const fakeKlendIxs = await getKlendIxs(args, FAKE_TARGET_COLL_SWAP_OUT_AMOUNT, context, scopeRefreshIxn);
165
174
  const klendAccounts = uniqueAccountsWithProgramIds(listIxs(fakeKlendIxs));
166
175
 
167
176
  // Construct the external swap ixs (and learn the actual swap-out amount):
@@ -176,7 +185,7 @@ export async function getSwapCollIxs<QuoteResponse>(
176
185
  checkResultingObligationValid(args, externalSwapIxs.swapOutAmount, context);
177
186
 
178
187
  // Construct the Klend's own ixs with an actual swap-out amount:
179
- const klendIxs = await getKlendIxs(args, externalSwapIxs.swapOutAmount, context);
188
+ const klendIxs = await getKlendIxs(args, externalSwapIxs.swapOutAmount, context, scopeRefreshIxn);
180
189
 
181
190
  return {
182
191
  ixs: listIxs(klendIxs, externalSwapIxs.ixs),
@@ -270,19 +279,12 @@ type SwapCollKlendIxs = {
270
279
  async function getKlendIxs(
271
280
  args: SwapCollArgs,
272
281
  targetCollSwapOutAmount: Decimal,
273
- context: SwapCollContext<any>
282
+ context: SwapCollContext<any>,
283
+ scopeRefreshIxn: TransactionInstruction[]
274
284
  ): Promise<SwapCollKlendIxs> {
275
285
  const { ataCreationIxs, targetCollAta } = getAtaCreationIxs(context);
276
286
  const setupIxs = [...context.budgetAndPriorityFeeIxs, ...ataCreationIxs];
277
287
 
278
- const scopeRefreshIxn = await getScopeRefreshIx(
279
- context.market,
280
- context.sourceCollReserve,
281
- context.targetCollReserve,
282
- context.obligation,
283
- context.scopeRefreshConfig
284
- );
285
-
286
288
  if (scopeRefreshIxn) {
287
289
  setupIxs.unshift(...scopeRefreshIxn);
288
290
  }