@kamino-finance/klend-sdk 5.2.2 → 5.2.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.
@@ -18,8 +18,6 @@ import {
18
18
  KaminoMarket,
19
19
  KaminoReserve,
20
20
  lamportsToDecimal,
21
- LendingMarket,
22
- MarketWithAddress,
23
21
  PubkeyHashMap,
24
22
  Reserve,
25
23
  WRAPPED_SOL_MINT,
@@ -50,7 +48,7 @@ import {
50
48
  import { VaultConfigFieldKind } from '../idl_codegen_kamino_vault/types';
51
49
  import { VaultState } from '../idl_codegen_kamino_vault/accounts';
52
50
  import Decimal from 'decimal.js';
53
- import { getTokenBalanceFromAccountInfoLamports, numberToLamportsDecimal, parseTokenSymbol } from './utils';
51
+ import { bpsToPct, getTokenBalanceFromAccountInfoLamports, numberToLamportsDecimal, parseTokenSymbol } from './utils';
54
52
  import { deposit } from '../idl_codegen_kamino_vault/instructions';
55
53
  import { withdraw } from '../idl_codegen_kamino_vault/instructions';
56
54
  import { PROGRAM_ID } from '../idl_codegen/programId';
@@ -348,22 +346,12 @@ export class KaminoVaultClient {
348
346
  }
349
347
 
350
348
  const reserveState = reserveStates[index]!;
351
-
352
- const market = reserveState.lendingMarket;
353
- const marketState = await LendingMarket.fetch(this._connection, market, this._kaminoLendProgramId);
354
- if (marketState === null) {
355
- throw new Error(`Market ${market.toBase58()} not found`);
356
- }
357
-
358
- const marketWithAddress = {
359
- address: market,
360
- state: marketState,
361
- };
349
+ const marketAddress = reserveState.lendingMarket;
362
350
 
363
351
  return this.withdrawPendingFeesIxn(
364
352
  vault,
365
353
  vaultState,
366
- marketWithAddress,
354
+ marketAddress,
367
355
  { address: reserve, state: reserveState },
368
356
  adminTokenAta
369
357
  );
@@ -389,7 +377,6 @@ export class KaminoVaultClient {
389
377
  * @param user - user to deposit
390
378
  * @param vault - vault to deposit into
391
379
  * @param tokenAmount - token amount to be deposited, in decimals (will be converted in lamports)
392
- * @param tokenProgramIDOverride - optional param; should be passed if token to be deposited is token22
393
380
  * @param vaultReservesMap - optional parameter; a hashmap from each reserve pubkey to the reserve state. If provided the function will be significantly faster as it will not have to fetch the reserves
394
381
  * @returns - an array of instructions to be used to be executed
395
382
  */
@@ -397,12 +384,11 @@ export class KaminoVaultClient {
397
384
  user: PublicKey,
398
385
  vault: KaminoVault,
399
386
  tokenAmount: Decimal,
400
- tokenProgramIDOverride?: PublicKey,
401
387
  vaultReservesMap?: PubkeyHashMap<PublicKey, KaminoReserve>
402
388
  ): Promise<TransactionInstruction[]> {
403
389
  const vaultState = await vault.getState(this._connection);
404
390
 
405
- const tokenProgramID = tokenProgramIDOverride ? tokenProgramIDOverride : TOKEN_PROGRAM_ID;
391
+ const tokenProgramID = vaultState.tokenProgram;
406
392
  const userTokenAta = getAssociatedTokenAddress(vaultState.tokenMint, user, true, tokenProgramID);
407
393
  const createAtasIxns: TransactionInstruction[] = [];
408
394
  const closeAtasIxns: TransactionInstruction[] = [];
@@ -487,15 +473,18 @@ export class KaminoVaultClient {
487
473
  user: PublicKey,
488
474
  vault: KaminoVault,
489
475
  shareAmount: Decimal,
490
- slot: number
476
+ slot: number,
477
+ vaultReservesMap?: PubkeyHashMap<PublicKey, KaminoReserve>
491
478
  ): Promise<TransactionInstruction[]> {
492
479
  const vaultState = await vault.getState(this._connection);
493
480
 
481
+ const vaultReservesState = vaultReservesMap ? vaultReservesMap : await this.loadVaultReserves(vaultState);
482
+
494
483
  const userSharesAta = getAssociatedTokenAddress(vaultState.sharesMint, user);
495
484
  const [{ ata: userTokenAta, createAtaIx }] = createAtasIdempotent(user, [
496
485
  {
497
486
  mint: vaultState.tokenMint,
498
- tokenProgram: TOKEN_PROGRAM_ID,
487
+ tokenProgram: vaultState.tokenProgram,
499
488
  },
500
489
  ]);
501
490
 
@@ -531,40 +520,31 @@ export class KaminoVaultClient {
531
520
  });
532
521
  }
533
522
 
534
- const reserveStates = await Reserve.fetchMultiple(this._connection, reservesToWithdraw, this._kaminoLendProgramId);
535
- const withdrawIxns: TransactionInstruction[] = await Promise.all(
536
- reservesToWithdraw.map(async (reserve, index) => {
537
- if (reserveStates[index] === null) {
538
- throw new Error(`Reserve ${reserve.toBase58()} not found`);
539
- }
523
+ const withdrawIxns: TransactionInstruction[] = [];
524
+ withdrawIxns.push(createAtaIx);
540
525
 
541
- const reserveState = reserveStates[index]!;
542
-
543
- const market = reserveState.lendingMarket;
544
- const marketState = await LendingMarket.fetch(this._connection, market, this._kaminoLendProgramId);
545
- if (marketState === null) {
546
- throw new Error(`Market ${market.toBase58()} not found`);
547
- }
548
-
549
- const marketWithAddress = {
550
- address: market,
551
- state: marketState,
552
- };
526
+ reservesToWithdraw.forEach((reserve, index) => {
527
+ const reserveState = vaultReservesState.get(reserve);
528
+ if (reserveState === undefined) {
529
+ throw new Error(`Reserve ${reserve.toBase58()} not found in vault reserves map`);
530
+ }
553
531
 
554
- return this.withdrawIxn(
555
- user,
556
- vault,
557
- vaultState,
558
- marketWithAddress,
559
- { address: reserve, state: reserveState },
560
- userSharesAta,
561
- userTokenAta,
562
- amountToWithdraw[index]
563
- );
564
- })
565
- );
532
+ const marketAddress = reserveState.state.lendingMarket;
533
+ const withdrawFromReserveIx = this.withdrawIxn(
534
+ user,
535
+ vault,
536
+ vaultState,
537
+ marketAddress,
538
+ { address: reserve, state: reserveState.state },
539
+ userSharesAta,
540
+ userTokenAta,
541
+ amountToWithdraw[index],
542
+ vaultReservesState
543
+ );
544
+ withdrawIxns.push(withdrawFromReserveIx);
545
+ });
566
546
 
567
- return [createAtaIx, ...withdrawIxns];
547
+ return withdrawIxns;
568
548
  }
569
549
 
570
550
  /**
@@ -646,17 +626,18 @@ export class KaminoVaultClient {
646
626
  return [createAtaIx, investIx];
647
627
  }
648
628
 
649
- private async withdrawIxn(
629
+ private withdrawIxn(
650
630
  user: PublicKey,
651
631
  vault: KaminoVault,
652
632
  vaultState: VaultState,
653
- marketWithAddress: MarketWithAddress,
633
+ marketAddress: PublicKey,
654
634
  reserve: ReserveWithAddress,
655
635
  userSharesAta: PublicKey,
656
636
  userTokenAta: PublicKey,
657
- shareAmountLamports: Decimal
658
- ): Promise<TransactionInstruction> {
659
- const lendingMarketAuth = lendingMarketAuthPda(marketWithAddress.address, this._kaminoLendProgramId)[0];
637
+ shareAmountLamports: Decimal,
638
+ vaultReservesState: PubkeyHashMap<PublicKey, KaminoReserve>
639
+ ): TransactionInstruction {
640
+ const lendingMarketAuth = lendingMarketAuthPda(marketAddress, this._kaminoLendProgramId)[0];
660
641
 
661
642
  const withdrawAccounts: WithdrawAccounts = {
662
643
  user: user,
@@ -667,12 +648,12 @@ export class KaminoVaultClient {
667
648
  sharesMint: vaultState.sharesMint,
668
649
  userSharesAta: userSharesAta,
669
650
  tokenAta: userTokenAta,
670
- tokenProgram: TOKEN_PROGRAM_ID,
651
+ tokenProgram: vaultState.tokenProgram,
671
652
  instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
672
653
  reserve: reserve.address,
673
654
  ctokenVault: getCTokenVaultPda(vault.address, reserve.address, this._kaminoVaultProgramId),
674
655
  /** CPI accounts */
675
- lendingMarket: marketWithAddress.address,
656
+ lendingMarket: marketAddress,
676
657
  lendingMarketAuthority: lendingMarketAuth,
677
658
  reserveLiquiditySupply: reserve.state.liquidity.supplyVault,
678
659
  reserveCollateralMint: reserve.state.collateral.mintPubkey,
@@ -688,7 +669,6 @@ export class KaminoVaultClient {
688
669
  const withdrawIxn = withdraw(withdrawArgs, withdrawAccounts, this._kaminoVaultProgramId);
689
670
 
690
671
  const vaultReserves = this.getVaultReserves(vaultState);
691
- const vaultReservesState = await this.loadVaultReserves(vaultState);
692
672
 
693
673
  let vaultReservesAccountMetas: AccountMeta[] = [];
694
674
  let vaultReservesLendingMarkets: AccountMeta[] = [];
@@ -715,11 +695,11 @@ export class KaminoVaultClient {
715
695
  private async withdrawPendingFeesIxn(
716
696
  vault: KaminoVault,
717
697
  vaultState: VaultState,
718
- marketWithAddress: MarketWithAddress,
698
+ marketAddress: PublicKey,
719
699
  reserve: ReserveWithAddress,
720
700
  adminTokenAta: PublicKey
721
701
  ): Promise<TransactionInstruction> {
722
- const lendingMarketAuth = lendingMarketAuthPda(marketWithAddress.address, this._kaminoLendProgramId)[0];
702
+ const lendingMarketAuth = lendingMarketAuthPda(marketAddress, this._kaminoLendProgramId)[0];
723
703
 
724
704
  const withdrawPendingFeesAccounts: WithdrawPendingFeesAccounts = {
725
705
  adminAuthority: vaultState.adminAuthority,
@@ -732,7 +712,7 @@ export class KaminoVaultClient {
732
712
  tokenMint: vaultState.tokenMint,
733
713
  tokenProgram: TOKEN_PROGRAM_ID,
734
714
  /** CPI accounts */
735
- lendingMarket: marketWithAddress.address,
715
+ lendingMarket: marketAddress,
736
716
  lendingMarketAuthority: lendingMarketAuth,
737
717
  reserveLiquiditySupply: reserve.state.liquidity.supplyVault,
738
718
  reserveCollateralMint: reserve.state.collateral.mintPubkey,
@@ -829,6 +809,18 @@ export class KaminoVaultClient {
829
809
  return vaultUserShareBalance;
830
810
  }
831
811
 
812
+ /**
813
+ * This method returns the management and performance fee percentages
814
+ * @param vaultState - vault to retrieve the fees percentages from
815
+ * @returns - VaultFeesPct containing management and performance fee percentages
816
+ */
817
+ getVaultFeesPct(vaultState: VaultState): VaultFeesPct {
818
+ return {
819
+ managementFeePct: bpsToPct(new Decimal(vaultState.managementFeeBps.toString())),
820
+ performanceFeePct: bpsToPct(new Decimal(vaultState.performanceFeeBps.toString())),
821
+ };
822
+ }
823
+
832
824
  /**
833
825
  * This method calculates the token per shar value. This will always change based on interest earned from the vault, but calculating it requires a bunch of rpc requests. Caching this for a short duration would be optimal
834
826
  * @param vault - vault to calculate tokensPerShare for
@@ -1275,10 +1267,15 @@ export class KaminoVaultClient {
1275
1267
  totalInvested = totalInvested.add(reserveAllocationLiquidityAmount);
1276
1268
  totalBorrowed = totalBorrowed.add(reserveAllocationLiquidityAmount.mul(utilizationRatio));
1277
1269
  });
1270
+
1271
+ let utilizationRatio = new Decimal(0);
1272
+ if (!totalInvested.isZero()) {
1273
+ utilizationRatio = totalBorrowed.div(totalInvested);
1274
+ }
1278
1275
  return {
1279
1276
  totalInvested: totalInvested,
1280
1277
  totalBorrowed: totalBorrowed,
1281
- utilizationRatio: totalBorrowed.div(totalInvested),
1278
+ utilizationRatio: utilizationRatio,
1282
1279
  };
1283
1280
  }
1284
1281
 
@@ -1526,3 +1523,8 @@ export type VaultOverview = {
1526
1523
  totalBorrowed: Decimal;
1527
1524
  utilizationRatio: Decimal;
1528
1525
  };
1526
+
1527
+ export type VaultFeesPct = {
1528
+ managementFeePct: Decimal;
1529
+ performanceFeePct: Decimal;
1530
+ };
@@ -643,6 +643,25 @@ async function main() {
643
643
  });
644
644
  });
645
645
 
646
+ commands
647
+ .command('get-vault-overview')
648
+ .requiredOption('--vault <string>', 'Vault address')
649
+ .action(async ({ vault }) => {
650
+ const env = initializeClient(false, false);
651
+
652
+ const kaminoManager = new KaminoManager(env.connection, env.kLendProgramId, env.kVaultProgramId);
653
+
654
+ const vaultAddress = new PublicKey(vault);
655
+ const vaultState = await new KaminoVault(vaultAddress, undefined, env.kVaultProgramId).getState(env.connection);
656
+ const vaultOverview = await kaminoManager.getVaultOverview(
657
+ vaultState,
658
+ await env.connection.getSlot('confirmed'),
659
+ new Decimal(1.0)
660
+ );
661
+
662
+ console.log('vaultOverview', vaultOverview);
663
+ });
664
+
646
665
  commands
647
666
  .command('get-user-shares-for-vault')
648
667
  .requiredOption('--vault <string>', 'Vault address')